bit*_*007 15 multithreading executorservice fork-join executors forkjoinpool
使用中的低级差异是什么:
ForkJoinPool = new ForkJoinPool(X);
Run Code Online (Sandbox Code Playgroud)
和
ExecutorService ex = Executors.neWorkStealingPool(X);
Run Code Online (Sandbox Code Playgroud)
其中X是所需的并行级别,即线程运行..
根据文档我发现它们相似.还告诉我哪一个在任何正常用途下更合适和安全.我有1.3亿个条目写入BufferedWriter并使用Unix排序按第1列排序.
另请告诉我如果可能的话要保留多少个线程.
注意:我的系统有 8个核心处理器和 32 GB RAM.
Dav*_*aim 23
工作窃取是现代线程池使用的一种技术,用于减少对工作队列的争用.
经典线程池有一个队列,每个线程池线程锁定队列,使任务出列,然后解锁队列.如果任务很短并且有很多任务,那么队列上存在很多争用.使用无锁队列确实有帮助,但并不能完全解决问题.
现代线程池使用工作窃取 - 每个线程都有自己的队列.当线程池线程产生一个任务时 - 它将它排入自己的队列.当线程池线程想要使任务出列时 - 它首先尝试将任务从自己的队列中出列,如果它没有任何 - 它从其他线程队列中"窃取"工作.这确实减少了theradpool的争用并提高了性能.
newWorkStealingPool 创建一个利用工作用途的线程池,其线程数为处理器数.
newWorkStealingPool提出了一个新问题.如果我有四个逻辑核心,那么池总共有四个线程.如果我的任务阻止 - 例如在同步IO上 - 我没有充分利用我的CPU.我想要的是在任何给定时刻的四个活动线程,例如 - 加密AES的四个线程和等待IO完成的另外140个线程.
这就是ForkJoinPool提供 - 如果您的任务产生新任务并且任务等待它们完成 - 池将注入新的活动线程以使CPU饱和.值得一提的是,ForkJoinPool利用偷工作也是如此.
哪一个用?如果您使用fork-join模型或者您知道任务无限期阻塞,请使用ForkJoinPool.如果您的任务很短并且主要受CPU限制,请使用newWorkStealingPool.
在说完任何事情之后,现代应用程序倾向于使用具有可用处理器数量的线程池,并利用异步IO和无锁容器来防止阻塞.这(通常)给出了最佳性能.
newWorkStealingPool是更高级别的抽象ForkJoinPool。
如果您查看 Oracle jvm 实现,它只是一个预先配置的ForkJoinPool:
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null,
true);
}
Run Code Online (Sandbox Code Playgroud)
不幸的是,查看实现并不是理解类目的的正确方法。
也归功于:https : //dzone.com/articles/diving-into-java-8s-newworkstealingpools
| 归档时间: |
|
| 查看次数: |
5936 次 |
| 最近记录: |