概述及架构
线程池特点:
- 可以降低资源消耗,通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度:任务到达时,可以不需要等待线程创建就能立即执行
- 提高线程的可管理性:线程是稀缺资源,无限制创建会消耗系统资源,降低系统稳定性。用线程池可以统一分配、调优和监控
架构–Executor框架实现
线程池的使用
- 一池N线程: Executors.newFixedThreadPool(int)
- 一池一线程 : Executors.newSingleThreadExecutor()
- 可扩容线程池 :Executors.newCachedThreadPool()
底层都是用的ThreadPoolExecutor
public class ThreadPoolDemo1 {
public static void main(String[] args) {
// 一池五线程
ExecutorService threadPool1 = Executors.newFixedThreadPool(5); //五个窗口
//一池一线程
ExecutorService threadPool2 = Executors.newSingleThreadExecutor();
//一池可扩容的线程
ExecutorService threadPool3 = Executors.newCachedThreadPool();
//10个顾客请求
try {
for (int i = 1; i < 21; i++) {
threadPool3.execute(() -> {
System.out.println(Thread.currentThread().getName() + "--正在办理业务");
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
});
}
}finally {
threadPool3.shutdown();
}
}
}
ThreadPoolExecutor 七个参数含义
- int corePoolSize, 常驻线程数量(核心)
- int maximumPoolSize 最大线程数量
- long keepAliveTime,线程存活时间
- TimeUnit unit , 时间单位
- BlockingQueue workQueue ,阻塞队列
- ThreadFactory threadFactory, 线程工厂
- RejectedExecutionHandler handler,拒绝策略
线程底层工作流程
在执行execute()方法的时候才开始创建线程,根据需求先创建常驻线程,然后再来需求进入阻塞队列, 再来需求创建更多线程直接进行处理,再来需求执行拒绝策略
四种拒绝策略
- AbortPolicy (默认): 直接抛出异常,阻止系统正常运行
- CallerRunsPolicy: 不会抛弃任务,也不会抛出异常,而是将某些任务回退给调用者
- DiscardOldestPolicy: 抛弃队列中等待最久的任务,然后把当前任务加入队列中尝试再次提交当前任务
- DiscardPolicy:不做任何处理
自定义线程池
public class ThreadPoolDemo2 {
public static void main(String[] args) {
//1.常驻线程数量, 2.最大线程数量, 3.线程存活时间 4.时间单位, 5.阻塞队列, 6.线程工厂, 7.拒绝策略
ThreadPoolExecutor threadPool = new ThreadPoolExecutor(
2,
5,
2L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
//10个顾客请求
try {
for (int i = 1; i <= 8; i++) {
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "--正在办理业务");
// try {
// Thread.sleep(2000);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
});
}
}finally {
threadPool.shutdown();
}
}
}