线程池的由来
- 首先,进程是什么?线程是什么?并行是什么?并发是什么?
进程
:是计算机中一个集多个服务于一体,完成某一需要任务的应用集成。诸如:QQ、微信、酷狗、淘宝。
线程
:是计算机处理信息最小的一个量度单位,可以形象地认为是QQ应用程序中,发送一条消息的线程,多条刷新空间后更新内容的线程等。一个进程一定有一个或多个线程。
并行
:电脑存在多个CPU核,例如博主电脑只有四核,于是最多有四个线程在同时运行的话,这四个线程就为并行状态。
并发
:并发其实也是为了模拟并行状态,只是内核不够,只能通过迅速切换线程的上下文,达到并行的效果。但是实际仍然是顺序运行。
- 在前面的博文中,写了关于多线程的相关内容,但是多线程在创建和销毁时,很损耗计算机的性能,所以不如直接创建一个拥有诸多线程的池子。
- 这样的好处:
- 1、减少线程创建、销毁的消耗
- 2、方便线程管理,相当于增加了线程监管部门
- 3、控制线程的并发控制,避免产生死锁等现象。
线程池的创建方法
不推荐的方法
- 线程创建有很多中方法,在此只说四个方法。这些方法,作为创建线程的方式,现如今不大被提倡。特别是在阿里巴巴的内部手册中多次提到
- 创建线程池的方式最好不要使用这些方法:
newSingelThreadExecutor
:作为拥有单个线程的线程池,想起来一定觉得很奇怪,但是事实就是拥有一个线程。这个线程池虽然拥有一个线程,但是它会自动创建和销毁线程,免去了我们创建的麻烦,适合多次单个线程操作某个资源。
newFixedThreadExecutor
:固定大小线程的线程池,线程池的数量自己定义,防止线程创建过多影响性能,当运行的线程数量大于设定线程数时,就会进入等待队列,进行等待。
newScheduledThreadExecutor
:创建一个线程池,可以调度命令在给定的延迟之后运行,或定期执行。
newCachedThreadExecutor
:可以伸缩的线程池,无需关心大小,直接使用,比较有弹性,但是不适合管理,因为这样会增加内存负担以及管理难度。
较推荐的方法
- 使用ThreadPoolExecutor对线程进行创建,为什么会推荐使用该方法取创建线程池,因为它可以手动设置线程池的参数,这样有利于我们对线程池内部进行管理和设计,比较推荐。
- 创建该线程池需要7个参数,下面就一一介绍七个参数的内容
new ThreadPoolExecutor(
3, //核心线程数
5, //最大线程数
1, //超时时间
TimeUnit.SECONDS, //超时单位
new LinkedBlockingQueue<>(), //阻塞队列,使用链表阻塞队列
Executor.defaultThreadFactory, //默认创建工厂
new ThreadExecutor.AbortPolicy //拒绝策略
);
参数解释
- 核心线程数:
核心线程数,作为线程池核心运行的线程数,在运行过程中作为主要运行的线程数。
- 最大线程数
最大线程数,在阻塞队列排满,且仍然有线程请求的情况下,则需要使用
最大线程-核心线程
的线程窗口允许运行线程。相当于打开了平时不用的临时窗口。
- 超时时间、时间单位
当
最大线程-核心线程
的线程不再使用,且到达了规定的时间,则关闭这些临时运行窗口,再次使用核心线程数来运行线程数量。
- 阻塞队列
在线程数量大于核心线程数,且小于核心线程数+阻塞队列数时,我们创建的线程会暂时存放在阻塞队列中。如果阻塞队列都满了,则会考虑临时线程窗口。
- 创建工厂
创建线程的工厂,一般使用默认工厂即可,无需太关心具体参数
- 拒绝策略
拒绝策略分为四种,分别为:AbortPolicy、DiscardPolicy、DiscardOldestPolicy和CallerRunsPolicy。
拒绝策略详解
- AbortPolicy:默认拒绝策略
当线程请求创建数超过最大线程数时,直接抛出异常,RejectedExecutionPoolSize。
- DiscardPolicy:丢弃拒绝策略
当线程创建大于最大线程数时,不抛出异常,直接丢弃该线程
- DiscardOldestPolicy:丢弃最老线程
大于最大线程数时,不抛出异常,丢弃最前面的线程
- CallerRunsPolicy:调用处理
由调用该方法的线程来处理该问题。
结语
- 本次是对线程池的简单介绍,如有疑问或错误,欢迎留言交流。