使用SynchronousQueue的ThreadPoolExecutor拒绝任务,如何避免及确保任务串行执行
如何确保前一个任务完全执行完毕,且工作线程已准备好接收新任务?
如下代码在部分设备上会拒绝第二个任务:
ThreadPoolExecutor exe = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.SECONDS, new SynchronousQueue<>()); Future future = exe.submit(task1); while (!future.isDone()) { // 做一些操作,等待结果 sleep(1); } Future future = exe.submit(task2); // 有时会拒绝该任务
我曾遇到类似未解决的问题。
更新:栈追踪信息
java.util.concurrent.RejectedExecutionException: Task java.util.concurrent.ExecutorCompletionService$QueueingFuture@8c1e52e[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@6cdbdc4f[Wrapped task = java.util.concurrent.FutureTask@2aa7cf9b[Not completed, task = com.my.example.DatabaseValue$$Lambda$1438/0x0000000840650440@6c918fb6]]] rejected from java.util.concurrent.ThreadPoolExecutor@3aca79dd[Running, pool size = 1, active threads = 0, queued tasks = 0, completed tasks = 592] at java.base/java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2055) at java.base/java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:825) at java.base/java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1355) at java.base/java.util.concurrent.ExecutorCompletionService.submit(ExecutorCompletionService.java:184) ...
我无法在自己的设备上复现该问题,但它在其他设备上出现。
更新2:临时解决方案
现在我改用LinkedBlockingQueue(1)替代SynchronousQueue。此时线程池可提交2个任务,第一个处于活跃状态,第二个进入队列。为防止重复提交,我通过重写ThreadPoolExecutor.beforeExecute、ThreadPoolExecutor.afterExecute并在调用submit前检查无活跃任务来控制。
内容的提问来源于stack exchange,提问作者XorNut
相关产品推荐
相关产品推荐

