我有一个ExecutorService,如下所示-
ExecutorService executorSer = Executors.newFixedThreadPool(SIZE);我有一个元素列表( list )和一个操作(称为A),我需要在这个列表中的每个元素上应用它们。列表可以包含介于1到1000之间的任意数量的元素。该操作是可调用类型的。在operations内部,它调用另外两个服务B和C。B和C也作为异步操作运行,并提交到同一个线程池。
我已经为每个人创建了一个异步任务来并行执行这个任务,如下所示:
CompletionService<T> completionService = new ExecutorCompletionService<T>(executorSer);
completionService.submit(A) // this returns a Future<T>现在,我有了一个未来列表,然后循环得到结果。
如果我有一个非常大的线程池和列表中的少量元素,那么一切都可以正常工作。但是,如果线程池大小较小,而列表大小较大,则会遇到死锁。这是因为所有的Operation请求都会快速提交并占用线程池中的所有线程。每个操作-A在它提交的操作B和C的Future.get()上被阻塞。操作B和C任务只是坐在队列中等待线程。
因此,为了解决这个问题,我使用了ForkJoinPool。我简单地将newFixedThreadPool替换为ForkJoinPool,如下所示
ExecutorService executorSer = new ForkJoinPool(SIZE); 剩下的代码也没变。
这解决了我的问题。如果线程池大小较小,而列表大小较大,则现在不存在死锁。我的问题是,为什么?此外,当我打印线程名时,我看到线程号大于大小。它只是产生新的线程来解决死锁吗?
发布于 2016-02-27 23:21:24
在Executors.ForkJoinPool(SIZE)类中没有java.util.concurrent.Executors方法。但是,有Executors.newWorkStealingPool(int parallelism)方法来创建ForkJoinPool。正如JAVA所提到的那样:
并行级别对应于积极参与或可用于进行任务处理的线程的最大数量。线程的实际数量可能会动态增长和收缩。
这是你的答案。您提供的参数不是执行器将管理的实际线程的最大数量(与FixedThreadPool执行器的情况一样)。
https://stackoverflow.com/questions/35641699
复制相似问题