我有一个ExecutorService的创建如下 -的ExecutorService和ForkJoinPool
ExecutorService executorSer = Executors.newFixedThreadPool(SIZE);
我有元件(LIST)和操作(称为A),我需要应用在此列表中的每个元件上的列表。该列表可以包含1到1000之间的任意数量的元素。 该操作的类型为Callable。 在Operation-A内部,它调用了2个其他服务B和C. B和C也作为异步操作运行并提交给相同的线程池。
CompletionService<T> completionService = new ExecutorCompletionService<T>(executorSer);
completionService.submit(A) // this returns a Future<T>
现在我有未来的名单,我遍历得到()结果:
我有如下会为每个异步任务并行执行这一点。
如果我有一个非常大的线程池和LIST中的少量元素,一切正常。 但是,如果线程池SIZE很小并且LIST大小很大,我会遇到死锁。 这是因为所有Operation-A请求都很快提交并占用线程池中的所有线程。并且每个操作-A在其提交的操作B和C的Future.get()上被阻止。操作B和C任务只是坐在队列中等待获得一个线程。
因此,为了解决这个问题,我改用了ForkJoinPool。我简单地更换的newFixedThreadPool与ForkJoinPool如下
ExecutorService executorSer = new ForkJoinPool(SIZE);
,离开了其余代码相同。
这解决了我的问题。如果线程池SIZE很小并且LIST大小很大,现在没有死锁。 我的问题是,为什么? 此外,当我打印线程名称,我看到线程数大于SIZE。它只是产生新的线程来解决僵局?
更正:final ExecutorService executorSer = new ForkJoinPool(SIZE);是我用过的。 @iullianr:谢谢你指出。 – Patt