使用之间的低级区别是什么:
ForkJoinPool = new ForkJoinPool(X);
和
ExecutorService ex = Executors.neWorkStealingPool(X);
其中 X 是所需的并行度,即线程正在运行。
根据文档,我发现它们相似。还请告诉我,在任何正常使用情况下,哪种更合适,更安全。
我有 130个条目以写入BufferedWriter并使用Unix按第一列排序对它们进行排序。
如果可能的话,还要让我知道要保留多少个线程。
注:我的系统具有 8个核心处理器和 32 GB RAM。
最佳答案
工作窃取是现代线程池使用的一种技术,目的是减少工作队列上的争用。
经典线程池有一个队列,每个线程池线程都锁定队列,使任务出队,然后解锁队列。如果任务很短并且有很多任务,那么队列中就会有很多争用。在这里使用无锁队列确实有帮助,但不能完全解决问题。
现代线程池使用工作来窃取-每个线程都有自己的队列。当线程池线程产生任务时,它将任务排队到他自己的队列中。当线程池线程想要使任务出队时-它首先尝试将任务从他自己的队列中出队,如果没有,则从其他线程队列中“窃取”工作。这确实减少了线程池的争用并提高了性能。newWorkStealingPool
使用线程数作为处理器数来创建一个利用工作效率的线程池。newWorkStealingPool
提出了一个新问题。如果我有四个逻辑核心,则该池将总共有四个线程。如果我的任务阻塞(例如在同步IO上),则我的CPU使用率不足。我想要的是在给定的时间时在处有四个 Activity 线程,例如-四个对AES进行加密的线程和另外140个等待IO完成的线程。
这就是ForkJoinPool
提供的功能-如果您的任务产生了新任务,而该任务等待它们完成,则该池将注入(inject)新的 Activity 线程以使CPU饱和。值得一提的是,ForkJoinPool
也利用工作窃取。
使用哪一个?如果您使用fork-join模型,或者您无限期地知道任务阻塞,请使用ForkJoinPool
。如果您的任务很短并且大部分都是CPU限制,请使用newWorkStealingPool
。
言归正传,现代应用程序倾向于使用具有可用处理器数量的线程池,并利用异步IO 和无锁容器来防止阻塞。 (通常)可以提供最佳性能。
关于multithreading - Java8 ForkJoinPool和Executors.newWorkStealingPool之间的详细区别?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/41337451/