Java将可运行对象插入ExecutorService
我有一个单线程池ExecutorService对象。在将来的某个时候,将使用submit()方法添加要完成的任务。我的理解是submit会将Submited Runnable添加到待完成任务列表的末尾。但是,我有一种情况,基于布尔值,我可能希望将runnable提交到要执行的任务的前面。我不希望这会影响当前的任务,只希望下一个完成的任务就是我刚才给它的任务。下面重现了一个示例方法。我该怎么做 谢谢Java将可运行对象插入ExecutorService,java,threadpool,Java,Threadpool,我有一个单线程池ExecutorService对象。在将来的某个时候,将使用submit()方法添加要完成的任务。我的理解是submit会将Submited Runnable添加到待完成任务列表的末尾。但是,我有一种情况,基于布尔值,我可能希望将runnable提交到要执行的任务的前面。我不希望这会影响当前的任务,只希望下一个完成的任务就是我刚才给它的任务。下面重现了一个示例方法。我该怎么做 谢谢 private ExecutorService singleLoadPool = Executor
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);
}
我认为你最好的方法是用一个。具体来说,使用PriorityBlockingQueue构造函数,该构造函数接受。您的
比较器将是您用来实现“优先级”的
PriorityBlockingQueue<Runnable> workQueue = new PriorityBlockingQueue<Runnable>(20, yourPriorityComparator);
ExecutorService executorService = new ThreadPoolExecutor(1, 1, 1, TimeUnit.SECONDS, workQueue);
PriorityBlockingQueue workQueue=new PriorityBlockingQueue(20,您的PriorityComparator);
ExecutorService ExecutorService=新的ThreadPoolExecutor(1,1,1,TimeUnit.SECONDS,workQueue);
我的首选是使用LinkedBlockingDeque
。它直接支持位置插入/删除-putFirst(e)/takeFirst()
和putLast(e)/takeLast()
-这是您的主要需求-您不必为元素实现比较器。这也是有界的-这意味着它提供了针对OutOfMemoryError
的安全性
编辑以回答最新问题:
首先,让服务像
ExecutorService ExecutorService=new ThreadPoolExecutor(1,1,1,TimeUnit.SECONDS,workQueue)代码>
其次,重要的问题是:工作队列是什么
workQueue
是任何BlockingQueue
实现上的一个薄包装器,它将其所有方法委托给它包含的LinkedBlockingDeque
实例,除了offer()
方法,该方法由ThreadPoolExecutor
调用,并且需要重写,像这样:
public boolean offer(E e) {
if(doNow)
return linkedBlockingDequeInstance.offerFirst(e);
else
return linkedBlockingDequeInstance.offerLast(e);
}
当然,当您重写任何方法时,您需要小心地保护线程安全性及其总体契约。这显然需要仔细思考和严格测试。感谢您的回答,您能否提供一个优先级比较程序的示例?请查看Comparator
接口(现在已链接到答案中)。您可能需要实现自己的比较器
,但它应该相对简单。我的问题是我不知道如何将布尔值放入比较器。为了编译,我需要创建一个具有以下签名的类,私有类RunnableComparator实现Comparator。Comparator需要比较Runnable类型,不能比较实现Runnable的类,在ExecutorService可以实例化之前,只能有1个需要实例化的Comparator,因此doNow boolean不能传递给它。所以我正要实现它,还有一个问题,如何将作业添加到队列中?既然我不能只向LinkedBlockingDeque添加可运行对象,我是否必须重写ThreadPoolExecutor?