一 线程池优点
1、线程是稀缺资源,使用线程池可以减少创建和销毁线程的次数,重复利用提升使用效率。
2、因为重复利用之前创建的线程,加快了响应时间及速度。
3、方便调优与统一管理,如可根据系统的承受能力,调整线程池中工作线程的数量。
二 线程池实现原理
当一个任务通过线程池的execute(Runnable)方法添加到线程池时,其执行流程如下图所示:
1 当线程池中的数量小于corePool时,即使线程池中的线程都处于空闲状态,也会创建新的线程来处理被添加的任务。
2 当线程池中的数量等于 corePool时,但是缓冲队列 BlockingQueue未满,那么任务被放入缓冲队列。
3 当线程池中的数量大于corePool时,且缓冲队列BlockingQueue满,且线程池中的数量小于maximumPool时,在maximumPool新建线程来处理被添加的任务。
4 当线程池中的数量大于corePool,缓冲队列BlockingQueue满,并且线程池中的数量等于maximumPool时,那么通过RejectedExecutionHandler策略来处理此任务。也就是:处理任务的优先级为:核心线程corePool、任务队列BlockingQueue、最大线程maximumPool,如果三者都满了,使用RejectedExecutionHandler处理被拒绝的任务。 拒绝策略的四种实现,如上图所示。
三 拒绝策略及实例
JAVA提供了4种拒绝策略,默认配置是AbortPolicy。下面是详细解释:
1、AbortPolicy:直接抛出异常。
2、CallerRunsPolicy:不使用线程池执行任务,而是通过调用所在的(当前的)线程运行任务。
3、DiscardOldestPolicy:丢弃队列里最旧的一个任务,并将当前任务加入线程池以待执行。
4、DiscardPolicy:不处理,丢弃掉。
下面以AbortPolicy策略为例进行说明,其它情况类似。
public class AbortPolicyTest {
public static void main(String[] args) {
int corePoolSize = 5;
int maxPoolSize = 10;
long keepAliveTime = 5;
BlockingQueuequeue = new LinkedBlockingQueue(10);
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize,
maxPoolSize, keepAliveTime, TimeUnit.SECONDS, queue, handler);
for (int i = 0; i < 50; i++) {
executor.execute(new Worker());
}
executor.shutdown();
}
private static class Worker implements Runnable {
public void run() {
System.out.println(Thread.currentThread().getName() +
" is running");
}
}
}
此程序会抛出java.util.concurrent.RejectedExecutionException异常。
分享人:Gallen