ExecutorService和ForkJoinPool

我有一个ExecutorService创建如下 -

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。 我简单地使用ForkJoinPool替换newFixedThreadPool,如下所示

ExecutorService executorSer = new ForkJoinPool(SIZE); 

并保留其余代码相同。

这解决了我的问题。 如果线程池SIZE很小并且LIST大小很大,现在没有死锁。 我的问题是,为什么? 此外,当我打印线程名称,我看到线程数大于SIZE。 它只是产生新的线程来解决僵局?


java.util.concurrent.Executors类中没有Executors.ForkJoinPool(SIZE)方法。 但是,有创建ForkJoinPool的Executors.newWorkStealingPool(int parallelism)方法。 正如JAVA API提到的那样:

并行性级别对应于活跃参与或可用于参与任务处理的线程的最大数量。 线程的实际数量可能会动态增长和减少。

有你的答案。 您提供的参数不是执行程序将管理的实际线程的最大数量(例如, FixedThreadPool执行程序就是这种情况)。

链接地址: http://www.djcxy.com/p/35393.html

上一篇: ExecutorService and ForkJoinPool

下一篇: How should I spawn threads for parallel computation?