线程池就是一个可以复用线程的技术
用户每发起一个请求,后台就需要一个新的线程来处理,下次新的任务来了肯定又要创建新线程处理的,而创建新线程的开销是很大的,并且请求过多时,肯定会产生大量的线程出来,这样会严重影响系统的性能
(1)JDK5.0起提供了代表线程池的接口:ExecutorService
(2)得到线程池对象
方式一:使用ExecutorService的实现类ThreadPoolExecutor创建一个线程池对象
①ThreadPoolExecutor构造器:
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit,
BlockingQueue< Runnable> workQueue, ThreadFactory threadFactory,
RejectedExecutionHandler handler)
②线程池的注意事项
临时线程什么时候创建:新任务提交时发现核心线程都在忙,任务队列也满了,并且还可以创建临时线程,此时才会创建临时线程
什么时候会开始拒绝新任务:核心线程和临时线程都在忙,任务队列也满了,已经达到最大线程数量,新的任务过来的时候才会开始拒绝任务
public class Demo {
public static void main(String[] args) {
ThreadPoolExecutor pool = new ThreadPoolExecutor(
3, //核心线程数量
5, //最大线程数量
30, //临时线程存活时间
TimeUnit.SECONDS, //时间单位
new ArrayBlockingQueue<>(4), //任务队列
Executors.defaultThreadFactory(), //线程工厂
new ThreadPoolExecutor.AbortPolicy() //默认拒绝策略(拒绝服务,并且抛出异常)
);
}
}
/*线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险
Executors返回的线程池对象的弊端如下
FixedThreadPool、SingleThreadExecutor任务队列太长(Integer.MAX_VALUE)可能堆积大量请求,导致OOM
CachedThreadPool、ScheduledThreadPool最大线程数量太大(Integer.MAX_VALUE)可能堆积大量请求,导致OOM*/
③新任务拒绝策略
策略 | 详解 |
---|---|
ThreadPoolExecutor.AbortPolicy | 丢弃任务并抛出RejectedExecutionException异常。是默认的策略 |
ThreadPoolExecutor.DiscardPolicy | 丢弃任务,但是不抛出异常 这是不推荐的做法 |
ThreadPoolExecutor.DiscardOldestPolicy | 抛弃队列中等待最久的任务 然后把当前任务加入队列中 |
ThreadPoolExecutor.CallerRunsPolicy | 由主线程负责调用任务的run()方法从而绕过线程池直接执行 |
方式二:使用Executors(线程池工具类)调用方法返回不同特点的线程池对象
方法名称 | 说明 |
---|---|
public static ExecutorService newFixedThreadPool(int nThreads) | 创建固定线程数量的线程池,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程替代它。 |
public static ExecutorService newSingleThreadExecutor() | 创建只有一个线程的线程池对象,如果该线程出现异常而结束,那么线程池会补充一个新线程。 |
public static ExecutorService newCachedThreadPool() | 线程数量随着任务增加而增加,如果线程任务执行完毕且空闲了60s则会被回收掉。 |
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) | 创建一个线程池,可以实现在给定的延迟后运行任务,或者定期执行任务。 |
注意:线程池不允许使用Executors去创建,而是通过ThreadPoolExecutor的方式,这样的处理方式更加明确线程池的运行规则,规避资源耗尽的风险。Executors返回的线程池对象的弊端如下
FixedThreadPool、SingleThreadExecutor任务队列太长(Integer.MAX_VALUE)可能堆积大量请求,导致OOM(内存溢出)
CachedThreadPool、ScheduledThreadPool最大线程数量太大(Integer.MAX_VALUE)可能堆积大量请求,导致OOM