我想创建一个线程池,它将执行最近提交的任务。有关如何实现这一目标的任何建议吗?
谢谢
答案 0 :(得分:21)
您可能只需要实现自己的BlockingQueue
包装器,将offer / poll映射到堆栈。然后将其用作传递给BlockingQueue
的{{1}}实现。我的建议是包装一个现有的ThreadPoolExecutor
实现,例如ArrayDeque
。
Deque
方法(如果不是更奇特的东西)。 BlockingQueue
/ wait
条件。 notify
极性(“put”或“take”侧)映射到出队的同一端(将其视为一个堆)。 请注意,在更快的并发堆栈上有一些工作(参见Herlihy关于多处理器编程的艺术的书),但我不认为JDK中有任何实现,我不是确定Herlihy的实现是否会提供阻塞味道。
我为你检查了Android documentation, which suggests that Deque is around,所以这是一个实现。这也是在堆栈周围做包装的一个相当简单的步骤,但Deque是首选。
BlockingQueue
答案 1 :(得分:8)
类似于andersoj所建议的,但是可以使用BlockingDeque。
您可以将LinkedBlockingDeque类扩展为在提供和删除时始终弹出并按下。
public class FIFOBlockingDeque<T> extends LinkedBlockingDeque<T> {
@Override
public boolean offer(T t) {
return super.offerFirst(t);
}
@Override
public T remove() {
return super.removeFirst();
}
}
然后将其作为参数传递给ThreadPoolExecutor(BlockingDeque扩展BlockingQueue)
编辑: 要回答您的评论问题,您可以使用提供的java.util.Stack而不是继承Deque。它被认为是遗留的,如果你只局限于Java库本身,这将是最好的。
您可以使用push和pop来代替offerFirst和removeFirst。当然,您必须实现BlockingQueue并完成该实现。
答案 2 :(得分:1)
使用PriorityQueue
或PriorityBlockingQueue
可以轻松完成此操作,其中最近排队的项目具有最高优先级。
答案 3 :(得分:0)
ThreadPoolExecutor
构造函数接受用于保持任务执行的BlockingQueue
。您可能需要实现BlockingQueue
的自定义版本以支持LIFO策略。
答案 4 :(得分:0)
我认为在使用BlockingLifoQueue的方法中,LIFO的@andersoj实现中存在错误。
remove方法应该是这样的:
public T remove()
{
if (deque.isEmpty()) {
throw new NoSuchElementException("empty stack");
}
return deque.pollFirst(); // instead of pollLast()
}
对不起,如果我错了,但对我来说没有意义......在LIFO中查看最后一个。