目录
一、线程池参数介绍
二、线程池的工作流程
三、使用Executors创建常见的线程
一、线程池参数介绍
为了深入的了解线程池,这里就需要明白线程中的各种参数的含义。下述的图片中是来自于Java标准库中对线程池描述。
1.corePoolSize 与 maximumPoolSize
其中corePoolSize是当前线程池中核心线程的数量,maximumPoolSize是当前线程池中最大的线程量。一个线程池中为了效率最大化往往会创建出多个线程,这里最多的线程指的就是maximumPoolSize。但是当任务处理完之后,多个线程可能会消耗资源,所以就会销毁掉其他的非核心线程。
2.keepAliveTime 与 unit
当线程池中任务量不是很大的时候,这时候会考虑销毁掉部分的非核心线程。而这里的keepAliveTime就是非核心线程没有任务时的最大存活时间,如果在存活时间内又来了任务就不会销毁线程。这里的unit是存活时间的单位,例如毫秒、秒等。
3.workQueue 与 threadFactory
workQueue指的是阻塞队列,在线程池中可以使用内置的阻塞队列,也可以使用自定义的阻塞队列。threadFactory是工厂模式,通过这个工厂类来创建线程。
4.RejectedExecutionHandler handler
线程池中的拒绝策略,为了详细的认识拒绝策略,继续参考Java标准库。
ThreadPoolExecutor.AbortPolicy
直接抛出异常,终止线程池中所有的线程
ThreadPoolExecutor.CallerRunsPolicy
线程池将任务抛回,即哪个线程添加的任务就由哪个线程去执行,该任务还是要执行的
ThreadPoolExecutor.DiscardOldestPolicy
丢弃最早的任务,执行新的任务。这里就直接将最早的任务抛弃不执行了
ThreadPoolExecutor.DiscardPolicy
放弃新的任务,继续执行原来的任务。直接将新任务放弃不执行了
二、线程池的工作流程
在创建线程池的过程中,会直接创建好很多线程。当需要使用线程的时候,直接从线程池中取一个就行了,使用完了之后直接归还到线程中。
当出现任务量小于线程池中的核心线程数时就不会创建额外的线程,但是当线程数量小于任务量时,就会开始创建线程去解决这些任务,但是创建出来的线程也不会超过最大线程数量。同时,当阻塞队列中的任务满了之后,还有任务需要去解决,这时候已经创建不出来额外的线程了,就需要使用拒绝策略。
三、使用Executors创建常见的线程
Executors 创建线程池的几种方式
- newFixedThreadPool: 创建固定线程数的线程池
- newCachedThreadPool: 创建线程数目动态增长的线程池.
- newSingleThreadExecutor: 创建只包含单个线程的线程池.
- newScheduledThreadPool: 设定 延迟时间后执行命令,或者定期执行命令. 是进阶版的 Timer.
Executors 本质上是 ThreadPoolExecutor 类的封装
ExecutorService service = Executors.newFixedThreadPool(10);
service.submit(new Runnable(){
@Override
public void run() {
System.out.println("hello");
}
});
- 使用 Executors.newFixedThreadPool(10) 能创建出固定包含 10 个线程的线程池.
- 返回值类型为 ExecutorService
- 通过 ExecutorService.submit 可以注册一个任务到线程池中.