线程池入门到精通
什么是线程池
- 复用创建好的线程,节约创建和销毁的时间。
- 需要使用线程时,就从池子里拿一个空闲的线程,完成工作后,归还线程给线程池。
线程池工作原理
线程池工作流程
线程池生命周期及扩展点
线程池参数
JDK提供的线程池
线程池常见阻塞队列
线程池内置拒绝策略
线程池核心线程数设置
Fork/Join框架
执行逻辑
窃取原理
任务类图
例子
求开始数到结束数的和。
package org.mango.demo.mt.thread;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
/**
* 递归任务,带返回值的
* @Author: mango
* @Date: 2022/6/27 10:18 下午
*/
public class SumTask extends RecursiveTask<Long> implements Callable<Long> {
// 临界值
private static final int THRESHOLD = 10000;
private long start;
private long end;
public SumTask(long start,long end){
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
long sum = 0L;
boolean canSum = (end-start) < THRESHOLD;
if(canSum){
for(long i=start;i<=end;i++){
sum += i;
}
}else{
// 分成100个小任务
int count = 100;
long step = (end-start)/count;
List<SumTask> sumTasks = new ArrayList<>();
// 游标
long cursor = start;
for(int i=0;i<count;i++){
long theEnd = cursor + step;
if(theEnd > end){
theEnd = end;
}
SumTask sumTask = new SumTask(cursor,theEnd);
// 游标下移动
cursor += step + 1;
// 将任务加入集合,并开启子任务
sumTasks.add(sumTask);
sumTask.fork();
}
// 合并子任务结果
for (SumTask sumTask : sumTasks){
sum += sumTask.join();
}
}
return sum;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
ForkJoinPool forkJoinPool = new ForkJoinPool();
SumTask sumTask = new SumTask(1,123456789L);
Long result = forkJoinPool.invoke(sumTask);
System.out.println("结果为:"+result);
// ForkJoinTask<Long> forkJoinTask = forkJoinPool.submit(sumTask);
// try {
// Long result2 = forkJoinTask.get();
// } catch (InterruptedException e) {
// e.printStackTrace();
// } catch (ExecutionException e) {
// e.printStackTrace();
// }
ExecutorService executorService = Executors.newWorkStealingPool();
Future<Long> t = executorService.submit(sumTask);
Long result2 = t.get();
System.out.println(result2);
}
@Override
public Long call() throws Exception {
return compute();
}
}
参考文档
- https://www.zhihu.com/question/41134816
- 书籍:葛一鸣 *《Java高并发程序设计第二版》