当前位置: 首页 > 知识库问答 >
问题:

ExecutorService和ForkJoinpool

邢思淼
2023-03-14

我有一个ExecutorService创建如下-

ExecutorService executorSer = Executors.newFixedThreadPool(SIZE);

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

我为每个人创建了一个异步任务来并行执行,如下所示:

CompletionService<T> completionService =  new ExecutorCompletionService<T>(executorSer);
completionService.submit(A)  // this returns a Future<T>

现在我有了一个未来的列表,我在上面循环得到结果。

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

所以,为了解决这个问题,我改用了ForkJoinPool。我只是用ForkJoinPool替换了newFixedThreadPool,如下所示

ExecutorService executorSer = new ForkJoinPool(SIZE); 

剩下的代码保持不变。

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

共有1个答案

龙隐水
2023-03-14

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

并行级别对应于积极参与或可参与任务处理的最大线程数。线程的实际数量可能会动态增长和收缩。

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

 类似资料:
  • java.util.concurrent.ExecutorService接口是Executor接口的子接口,并添加了管理生命周期的功能,包括单个任务和执行程序本身。 ExecutorService方法 Sr.No. 方法和描述 1 boolean awaitTermination(long timeout, TimeUnit unit) 阻止所有任务在关闭请求之后完成执行,或发生超时,或者当前线程

  • 你能想一想为什么这段代码不起作用并且总是输出“finished”,但是第二个示例却没有任何问题地工作。我正在使用最新的JDK(8U45)。 下面的示例完美无缺: 编辑:添加返回和更新的睡眠时间和另一个例子。

  • 问题内容: 我们在Java中使用了三种不同的多线程技术 -Fork / Join pool,Executor Service和CountDownLatch 叉子/加入池 (http://www.javacodegeeks.com/2011/02/java-forkjoin-parallel- programming.html ) Fork / Join框架旨在使分治算法易于并行化。这种类型的算法非

  • 我对ExecutorService的javadoc#shutdown方法感到困惑。这些说法不矛盾吗? 启动有序关闭,其中执行以前提交的任务,但不接受新任务。此方法不会等待以前提交的任务完成执行。使用waitTersion执行此操作。 如果它能有序地关闭之前提交的任务,那么它怎么能等它们完成执行呢?

  • 我一直在尝试实现一个异步过程,其中父方法调用一个子方法,而子方法又会调用三个不同的方法。我希望所有的过程都是异步完成的,也就是说,在子方法中的这三个调用并行进行之后,控件应该返回到父方法,并继续执行它的其余部分。 我有这段代码,经过测试后效果很好。 现在,我的领导要求我使用这个,而不是。 我知道完全未来是从Java8开始的,但是第二个代码怎么会比第一个更好呢?因为,对于ExecutorServic

  • 我对和的内部调度机制有点困惑。 同时,显示为不同的,因为它使用了工作窃取算法。如果我理解正确,它意味着一个线程可以从另一个线程窃取一些任务。 然而,我并不真正理解和中实现的机制之间的区别。从我的理解来看,两种机制都应该尽可能减少每个线程的空闲时间。 如果在的情况下,每个线程都有自己的队列,我会理解的。然而,情况并非如此,因为队列是由池的不同线程共享的。