线程池的重要参数
1:核心线程数 int corePoolSize (好比就是1、2、3窗口)
2:最大线程数 int maximumPoolSize(好比就是1、2、3、4、5窗口)
3:空线程存活时间 long keepAliveTime (好比临时窗口按业务量来 如果业务少的时候就得关闭临时窗口 )
4:空线程存活时间单位TimeUnit (时间单位 分钟、秒)
5:工作队列 workQueue (ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、PriorityBlockingQueue、DelayQueue)
6:线程工厂 threadFactory (控制每个线程的生成)
7:拒绝策略 ejectedExecutionHandler (好比银行这个屋子里都排队满了还想办理业务的可以明天再来)
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, defaultHandler);
}
线程池的工作流程:
按业务量来算(根据照片来举例子考虑不同的情况):(首先要知道先来后到的顺序)
1:假如说我来的人是3个以内(人数<=3)
我们按照3个人算
就让核心线程数来解决(1、2、3)窗口可以处理完全快速不用排队的解决这三个人的业务
2:假如说我来的人数是6个人以内(3<人数<=6)
我们按照6个算自古以来都得排队按先来后到
就让排队的1、2、3号人去1、2、3窗口进行业务处理
剩下的4、5、6号人就到等候区(工作队列)去等待排队去然后等1、2、3人依次处理完
4、5、6号人就分别去按顺序的看谁先处理完任务就去哪个
3:假如说我来的人数是8个人以内(6<人数<=8)
我们按照8个人算
就让1、2、3号人排队的去1、2、3窗口去处理
剩下的4、5、6号人就到等候区(工作队列)去等待排队去剩下俩个人那怎么办
这时候就用到了临时窗口(也就是最大线程数减去核心线程数的数量)
这时候经理就看到业务多的情况就准备开放临时窗口召唤个临时工或者亲自上阵开放4、5窗口
这时候4、5就去临时窗口处理业务。然后6、7、8就去等候区(工作队列)去排队去
4:假如说我来的人数是9个人以上(人数>=9)
这时候好比这个银行排队的座位没有了这个屋子装不下了就得让第九个人明天再来处理业务
这就是线程池的原理
线程池的代码:
线程池配置类:
package com.example.hyzn.demos.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Configuration //声明他是一个配置类
public class threadPoolExecutorConfig {
@Bean
public ThreadPoolExecutor threadPoolExecutor() {
ThreadFactory threadFactory = new ThreadFactory() {//代表线程的创建
int count = 1;
@Override
public Thread newThread(Runnable r) {
Thread thread = new Thread(r);
thread.setName(thread.getName());
count++;
return thread;
}
};
/**
* 线程的管理
*/
ThreadPoolExecutor executor = new ThreadPoolExecutor(3, 5, 100, TimeUnit.SECONDS, new ArrayBlockingQueue<>(3), threadFactory);
return executor;
}
}
运用线程池的代码
package com.example.hyzn.demos.controller;
import cn.hutool.json.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
@RestController
@Slf4j
public class ThreadController {
@Resource
private ThreadPoolExecutor threadPoolExecutor;
@GetMapping("/add")
public void add(String name) {
CompletableFuture.runAsync(() -> {
log.info("任务执行中" + name + "执行人" + Thread.currentThread().getName());
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消息执行");
}, threadPoolExecutor);
}
@GetMapping("/get")
public String get(){
HashMap<String, Object> stringObjectHashMap = new HashMap<>();
int size = threadPoolExecutor.getQueue().size();
long taskCount = threadPoolExecutor.getTaskCount();
long completedTaskCount = threadPoolExecutor.getCompletedTaskCount();
int activeCount = threadPoolExecutor.getActiveCount();
stringObjectHashMap.put("队伍长度",size);
stringObjectHashMap.put("任务总数",taskCount);
stringObjectHashMap.put("已完成任务数",completedTaskCount);
stringObjectHashMap.put("正在工作的线程数",activeCount);
return JSONUtil.toJsonStr(stringObjectHashMap);
}
}
这个是第九个时候触发了拒绝策略 想要实践的大家动手实践把