Java将Runnable对象插入ExecutorService

时间:2012-08-01 19:50:53

标签: java threadpool

我有一个线程池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);
}

2 个答案:

答案 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);