文章目录
- 一.概述和架构
- 二.使用方式和底层原理
- 三.七个参数介绍
- 四.工作流程和拒绝策略
- 五.自定义线程池
一.概述和架构
一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能,而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务,这避免了在短时间任务时创建与销毁线程的代价,线程池不仅能够保证内核的充分利用,还能防止过分调度
线程池的优势:
线程池做的工作主要是控制运行的线程数量,处理过程中将任务放入队列,然后在线程创建后启动这些任务,如果线程数量超过了最大数量,超出数量的线程排队等候,等其他线程执行完毕,在从队列中取出任务来执行
特点:
-
降低资源消耗
:通过重复利用已创建的线程降低线程创建和销毁造成的消耗 -
提高响应速度
:当任务到达时,任务可以不需要等待线程创建就能立即执行 -
提高线程的可管理性
:线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以统一的进行分配,调优和监控 -
Java中的线程池是通过
Executor框架
实现的,该框架中用到了Executor,Executors
,ExecutorService,ThreadPoolExecutor这几个类
二.使用方式和底层原理
//线程池常用三种创建方式
public class ThreadPoolDemo1 {
public static void main(String[] args) {
//一池五线程
// ExecutorService threadPool1 = Executors.newFixedThreadPool(5);
//一池一线程
// ExecutorService threadPool2 = Executors.newSingleThreadExecutor();
//一池可扩容线程
ExecutorService threadPool3 = Executors.newCachedThreadPool();
try {
//10个顾客请求
for (int i = 0; i < 10; i++) {
//执行
threadPool3.execute(() -> {
System.out.println(Thread.currentThread().getName() + "办理业务");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//把线程池里的线程放回到线程池
threadPool3.shutdown();
}
}
}
我们创建线程池,底层都是new ThreadPoolExecutor(...)
三.七个参数介绍
四.工作流程和拒绝策略
第一步,在主线程中执行了executor()方法后,线程才会创建
第二步,执行了executor方法后,线程池创建的所有线程分为常驻线程和非常驻线程,当任务来时,首先被常驻线程处理
第三步,当常驻线程用完了,此时再来的任务就会被放到阻塞队列中
第四步,当阻塞队列满了以后,再来的任务,就会启动新线程来处理
第五步,当达到最大线程数,而且阻塞队列也满了,这时又来了一个任务,那这个任务就会被拒绝
五.自定义线程池
//自定义线程池
public class ThreadPoolDemo2 {
public static void main(String[] args) {
ExecutorService threadPool = new ThreadPoolExecutor(
2,
5,
2L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy()
);
try {
//10个顾客请求
for (int i = 0; i < 10; i++) {
//执行
threadPool.execute(() -> {
System.out.println(Thread.currentThread().getName() + "办理业务");
});
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//把线程池里的线程放回到线程池
threadPool.shutdown();
}
}
}
ckTrace();
} finally {
//把线程池里的线程放回到线程池
threadPool.shutdown();
}
}
}