特点
ForkJoinPool是Java中的一个特殊的线程池,用于执行可以分解为更小部分的任务,并且这些部分可以并行执行,特点是用来执行分治任务。思想是将大任务分解为小任务,然后继续将小任务分解,直至能够直接解决为止,然后再依次将任务的结果合并。
工作机制
ForkJoinPool采取工作窃取算法,以避免工作线程由于拆分了任务之后的join等待过程。这样处于空闲的工作线程将从其他工作线程的队列中主动去窃取任务来执行。(从其它队列尾部窃取任务,有兴趣的同学可以自行去查阅资料)
使用
1.例1
ForkJoinPool pool = new ForkJoinPool(3);
pool.submit(() -> {
// 业务
}).join();
pool.shutdown();
创建一个并行级别为3的线程池,提交任务,join等待任务完成,最后再关闭销毁资源。
2.例2
QwMarkForkJoinPool pool = new QwMarkForkJoinPool(3);
List<Integer> elements = Lists.newArrayList();
for (int i = 1; i <= 1000; i++) {
elements.add(i);
}
pool.submit(() -> elements.parallelStream().forEach(ele -> {
System.out.println(ele);
})).join();
pool.shutdown();
public class QwMarkForkJoinPool extends ForkJoinPool {
public QwMarkForkJoinPool(int poolSize) {
super(poolSize, QwMarkForkJoinWorkerThread::new,null,false);
}
}
public class QwMarkForkJoinWorkerThread extends ForkJoinWorkerThread {
/**
* Creates a ForkJoinWorkerThread operating in the given pool.
*
* @param pool the pool this thread works in
* @throws NullPointerException if pool is null
*/
protected QwMarkForkJoinWorkerThread(ForkJoinPool pool) {
super(pool);
setName("qwMarkThread-" + getId());
}
}
自定义线程池名称
3.例3
@Component
public class BizManager {
private QwMarkForkJoinPool pool;
@PostConstruct
public void init(){
pool = new QwMarkForkJoinPool(3);
}
public void bizMethod(){
pool.submit(() ->
// 业务
})).join();
}
}
接入到spring
Mark
每次submit任务后,都会创建新的work线程,至于线程什么时候会被销毁。销毁主要发生在整个线程池关闭且所有任务都执行完毕之后。核心线程会一直保持活跃直到线程池关闭,而非核心线程则会在空闲一段时间后销毁。目前还不清楚怎么设置核心线程数。