java - ExecutorService和ForkJoinPool

标签 java multithreading deadlock

我有一个ExecutorService创建如下-

ExecutorService executorSer = Executors.newFixedThreadPool(SIZE);

我有一个元素列表(LIST)和一个操作(称为A),需要将其应用于此列表中的每个元素。该列表可以包含1到1000之间的任意数量的元素。
该操作的类型为Callable。
在操作A内,它调用其他两个服务B和C。
B和C也作为异步操作运行,并提交到同一线程池。

我为每个创建了一个异步任务,以并行执行此任务,如下所示:
CompletionService<T> completionService =  new ExecutorCompletionService<T>(executorSer);
completionService.submit(A)  // this returns a Future<T>

现在,我有一个“ future 列表”,可以循环获取(结果)。

如果我的线程池非常大,而LIST中的元素数量很少,则一切正常。
但是,如果线程池SIZE很小而LIST大小很大,则会遇到死锁。
这是因为所有Operation-A请求都被快速提交并占用了线程池中的所有线程。并且每个操作A都在提交的操作B和C的Future.get()上被阻止。操作B和C的任务只是坐在队列中等待获取线程。

因此,要解决此问题,我改用了ForkJoinPool。我只是用ForkJoinPool替换了newFixedThreadPool,如下所示
ExecutorService executorSer = new ForkJoinPool(SIZE); 

其余代码保持不变。

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

最佳答案

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

The parallelism level corresponds to the maximum number of threads actively engaged in, or available to engage in, task processing. The actual number of threads may grow and shrink dynamically.



有你的答案。您提供的参数不是执行程序将管理的实际线程的最大数量(类似于FixedThreadPool执行程序的情况)。

关于java - ExecutorService和ForkJoinPool,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35641699/

相关文章:

java - 连接未被释放到多线程程序中的池

java - 为什么不能用 AtomicBoolean 标志中断可运行的任务?

deadlock - jvmti代理死锁

java - 为什么我的 javafx 阶段不想加载

java - 使用正则表达式和 java 的评论检测器

multithreading - 如何从 Perl 脚本中启动批处理文件并从中分离

java - 在这种情况下,ArrayList 是否会导致竞争条件或死锁?

等待已授予的锁的 Mysql 事务。这导致死锁

java - 如何将标准输入转换为字符串?

java - 使用 Jersey 2.0,如何为每个请求注册一个可绑定(bind)实例?