3.0 KiB
目录
- 线程池存在的意义
- 源码哔哔
线程池存在的意义
线程池存在的意义是降低资源消耗,通过重复利用已创建的线程降低线程创建和销毁造成的消耗,同时能够提高响应速度,当任务到达时,任务可以不需要等到线程创建就能够立即执行,起到缓存线程的效果。这种缓存对象实例的池化思想在 Android 中也有应用,比如 Handler 中使用到的 Message 消息池。
在 Java 中的线程池是用 ThreadPoolExecutor 类来实现的,它的构造方法中有一系列参数需要指定。首先是 corePoolSize 核心线程数量,当有任务通过 execute 方法提交时,如果当前运行的线程数 workCount 小于核心线程数,就新建一个线程去执行任务,如果 workCount 大于等于核心线程数并且队列未满时就扔进队列里面,等待有空闲的线程自己去从队列里面去取然后执行;如果此时队列满了,但是未达到最大线程数,就新建一个线程去执行任务,如果已经达到了最大线程数并且队列满了,就执行拒绝策略。第二个参数就是指定最大线程数,第三个参数是阻塞队列,在任务提交时,如果线程池中的线程数量大于等于 corePoolSize 时,就会把该任务封装成一个 Worker 对象放入等待队列里。在使用 Executors 的 newFixedThreadPool 或 newSingleThreadPool 创建线程池时使用的是 LinkedBlockingQueue,而在使用 newCachedThreadPool 使用的是 SynchronousQueue。但是通常不建议直接使用 Executors 创建线程池,因为 LinkedBlockingQueue 默认大小是 Integer.MAX_VALUE,可能会撑爆内存。第四个参数 keepAliveTime 是非核心线程的存活时间,第五个参数 threadFactory 是用来创建新线程的,默认是 DefaultThreadFactory,在 newThread 里面会设置线程的 group、优先级、是否是守护线程以及线程名称。最后一个参数是拒绝策略,默认是 AbortPolicy 直接抛异常。其次还有其他三个,这四个都定义在了 ThreadPoolExecutor 的内部类中,ThreadPoolExecutor 一共有五个内部类,还有一个就是上面讲到的 Worker。
然后再说说 ThreadPoolExecutor 的一个比较重要的字段,即原子类 ctl,它的高三位表示 runState 运行状态,后二十九位表示 workCount。线程池一共有五种运行状态,RUNNING 状态就是能够接受新提交的任务,并且也能处理阻塞队列中的任务;SHUTDOWN 关闭状态,就是不在接受新提交的任务,但却可以继续处理阻塞队列中已保存的任务,当调用 shutdown 方法会使线程池进入到该状态;STOP 状态不能接受新任务,也不处理队列中的任务,会尝试中断正在处理任务的线程,当调用 shutdownNow 时进行该状态;TIDYING 状态是所有任务已经终止了,workCount 为零。线程池进入该状态后就会调用 terminated 方法进入 TERMINATED 状态。