我有一个线程池ExecutorService对象。在将来的某个时间,使用submit()方法添加任务。我的理解是提交将提交将提交的Runnable添加到要完成的任务列表的末尾。但是我有一种情况,基于布尔我可能想要将runnable提交到要执行的任务的前面。我不希望这会影响当前的任务,只是下一个完成的任务将是我刚给它的任务。以下再现示例方法。我该怎么做?
由于
private ExecutorService singleLoadPool = Executors.newSingleThreadExecutor();
public void submitTask(Runnable run, boolean doNow) {
if (doNow)
singleLoadPool.submitFront(run); // This is the method I'm looking for
else
singleLoadPool.submit(run);
}
答案 0 :(得分:4)
我的偏好是使用LinkedBlockingDeque
。它直接支持位置插入/移除 - putFirst(e)/takeFirst()
和putLast(e)/takeLast()
- 这是您的主要要求 - 您不必为元素实现Comparator
。这也是有限的 - 这意味着它提供了对OutOfMemoryError
的安全性。
编辑回复最新问题:
首先,让ExecutorService像
一样 ExecutorService executorService = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, workQueue);
其次,重要的问题是:workQueue
是什么?
workQueue
是任何BlockingQueue
实现的瘦包装器,它将其所有方法委托给它包含的LinkedBlockingDeque
实例,但offer()
方法除外,由ThreadPoolExecutor
调用并且需要覆盖它,如下所示:
public boolean offer(E e) {
if(doNow)
return linkedBlockingDequeInstance.offerFirst(e);
else
return linkedBlockingDequeInstance.offerLast(e);
}
当你覆盖任何方法时 - 你需要小心保护线程安全及其一般合同。这无疑需要仔细考虑和严格测试。
答案 1 :(得分:1)
我认为您最好的方法是使用instantiate a ThreadPoolExecutor
PriorityBlockingQueue
。具体来说,使用引用Comparator
的PriorityBlockingQueue构造函数。您的Comparator
将用于实现“优先级”。
PriorityBlockingQueue<Runnable> workQueue = new PriorityBlockingQueue<Runnable>(20, yourPriorityComparator);
ExecutorService executorService = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, workQueue);