线程池的基本认识与使用
- 线程池
- 线程池工作原理:
- 优点:
- 传统的创建线程方式
- 线程池创建线程使用
线程池
- 池化思想:线程池、字符串常量池、数据库连接池
- 可以提高资源的利用率
线程池工作原理:
-
预先创建多个线程对象 放入线程池种,
-
有任务进来时候,线程池会给任务分配一个线程,执行结束之后再将线程放回线程池,
-
任务数量多于线程池中线程的数量的时候,没有分配到线程的任务会进入等待队列进行等待(等待队列的任务出入是先进先出后进后出),等线程使用完毕并释放进入线程池,再从线程池获取线程供等待队列中的任务使用。
-
等待队列中的等待任务到达等待队列的极限的时候,线程池就会创建新的线程,供队列外溢出的任务使用,
-
线程池中的线程达到上限了,没有空余的线程对象了,而等待队列中的任务也满了,还有任务溢出,将会触发线程池的拒绝策略。这样就可以做到线程资源的重复利用
优点:
- 提高给线程的利用率
- 提高程序的响应速度 线程对象是提前创建好的,使用之后也不会销毁,避免了线程创建和销毁的性能消耗,从而提高程序的相应速度
- 便于统一管理线程对象
- 可以控制最大的并发数
传统的创建线程方式
- 手动创建线程对象
- 执行任务
- 执行完毕,释放线程对象
线程利用率比较低
线程池创建线程使用
- 创建线程池,并配置相应的参数(创建线程池的方式有多种,这个后续再讨论。)
核心线程数量:线程池中基本存在的线程数量
线程池最大容量:线程池中的核心线都被执行任务,且等待队列爆满,扩展创建新线程后线程池的最大容量
线程存活时间:临时线程不被调用到 被销毁之间的间隔时间
时间单位:线程存活时间的单位
线程创建工厂:指定创建线程的工厂
拒绝策略:线程池达到最大容量,且等待队列爆满,对多余线程的处理方式。
- 创建线程之后,使用for循环模拟执行任务,最后关闭线程池
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
3,
5,
1L,
TimeUnit.SECONDS,
new ArrayBlockingQueue<>(3),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
for (int i = 0; i < 6; i++){
threadPoolExecutor.execute(() -> {
System.out.println(Thread.currentThread().getName() + "=======> 执行 ");
});
}
threadPoolExecutor.shutdown();
- 通过多次测试:
当执行任务<=核心线程数+等待队列容量
的时候线程池只使用核心线程处理任务,不会创建临时线程,
当核心线程数+等待队列容量<执行任务<=线程池最大容量+等待队列容量
的时候,线程池会创建临时线程处理溢出的在等待队列之外的程序。
当执行任务>线程池最大容量+等待队列容量
的时候,也就是线程池无法处理溢出的程序的时候,线程池会执行拒绝策略