5

我有一个单线程池 ExecutorService 对象。在将来的某个时候,添加任务以使用 submit() 方法完成。我的理解是 submit 会将提交的 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);
}
4

2 回答 2

4

我的偏好是使用LinkedBlockingDeque. 它直接支持位置插入/删除 -putFirst(e)/takeFirst()并且putLast(e)/takeLast()- 这是您的主要要求 - 您不必Comparator为您的元素实现 a。这也是有界的 - 这意味着它提供了针对OutOfMemoryError.

编辑针对最新问题:

首先,让 ExecutorService 像

ExecutorService executorService = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, workQueue);

其次,重要的问题是:什么是workQueue

是对任何 implementation的workQueue薄包装BlockingQueue,它将所有方法委托给LinkedBlockingDeque它包含的实例,除了offer()method ,它由 the 调用ThreadPoolExecutor并且需要被覆盖,如下所示:

       public boolean offer(E e) {
       if(doNow)
         return linkedBlockingDequeInstance.offerFirst(e);
      else 
         return linkedBlockingDequeInstance.offerLast(e);
   }

当然,当您覆盖任何方法时 - 您需要小心维护线程安全及其一般合同。这绝对需要仔细考虑和严格测试。

于 2012-08-01T20:37:19.390 回答
1

我认为你最好的方法是用 a实例化ThreadPoolExecutorPriorityBlockingQueuea 。具体来说,使用一个 PriorityBlockingQueue 构造函数,该构造函数接受Comparator. 你Comparator将是你用来实现你的“优先级”的东西。

PriorityBlockingQueue<Runnable> workQueue = new PriorityBlockingQueue<Runnable>(20, yourPriorityComparator);
ExecutorService executorService = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, workQueue);
于 2012-08-01T19:58:58.717 回答