newWorkStealingPool是任务窃取线程池,是Java8添加的线程池,用的是ForkJoinPool。
使用ForkJoinPool的好处是,把一个任务拆分成多个“小任务”,把这些“小任务”分发到多个线程上执行。这些“小任务”都执行完成后,再将结果合并。
之前的线程池中,多个线程共有一个阻塞队列,而newWorkStealingPool中每一个线程都有一个自己的队列。
当线程发现自己的队列没有任务了,就会到别的线程的队列里获取任务执行,可以简单理解为“窃取”。
一般是自己的本地队列采取LIFO(后进先出),窃取时采用FIFO(先进先出),一个从头开始执行,一个从尾开始执行,由于偷取的动作十分快速,会大量降低这种冲突,也是一种优化。
有2种实现,如下:
1、无参
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
Runtime.getRuntime().availableProcessors()是获取当前系统可以的CPU核心数。
2、有参
就一个参数parallelism,可以自定义并行度。
public static ExecutorService newWorkStealingPool(int parallelism) {
return new ForkJoinPool
(parallelism,
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
newWorkStealingPool测试案例
public class MyWork implements Runnable{
private int i;
public MyWork(int i){
this.i = i;
}
@Override
public void run() {
System.out.println(Thread.currentThread() +"正在执行,数值:"+this.i);
}
}
public class WorkStealing {
public static void main(String[] args) {
ExecutorService executorService = Executors.newWorkStealingPool(3);
for (int i=1; i<= 10; i++){
executorService.submit(new MyWork(i));
}
while (true){}
}
}
执行结果如下: