线程池的实现原理
下图所示为线程池的实现原理:调⽤⽅不断地向线程池中提交任务;线程池中有⼀组线程,不断地从队列中取任务,这是⼀个典型的⽣产者—消费者模型。
线程池的继承体系
线程池中的corePoolSize、maxPoolSize、blockingQueue、RejectedExecutionHandler这些参数是如何运作的
步骤⼀:判断当前线程数是否⼤于或等于corePoolSize。如果⼩于,则新建线程执⾏;如果⼤于,则进⼊步骤⼆。
步骤⼆:判断队列blockingQueue是否已满。如未满,则放⼊;如已满,则进⼊步骤三。
步骤三:判断当前线程数是否⼤于或等于maxPoolSize。如果⼩于,则新建线程执⾏;如果⼤于,则进⼊步骤四。
步骤四:根据拒绝策略RejectedExecutionHandler,拒绝任务
如何判断一个线程是否空闲
调用其tryLock()方法,如果没获取到锁,表示线程在忙,如果获取到了锁,表示线程是空闲的。
tryLock()方法核心也是cas操作,尝试将线程的状态变量从0变成1,操作成功返回true,失败返回false。
线程关闭时的状态变化
正确的关闭步骤:
executor.shutdown();
try {
boolean flag = true;
do {
flag = ! executor.awaitTermination(500, TimeUnit.MILLISECONDS);
} while (flag);
} catch (InterruptedException e) {
// ...
}
awaitTermination(…)⽅法的内部实现很简单:不断循环判断线程池是否到达了最终状态TERMINATED
shutdown()与shutdownNow()的区别
- shutdown()不会清空任务队列,会等所有任务执⾏完成,shutdownNow()清空任务队列。
- shutdown()只会中断空闲的线程,shutdownNow()会中断所有线程
线程关闭的核心过程:
shutdown():遍历workers,调用tryLock()判断线程是否空闲,是空闲,则调用interrupt()方法中断线程
shutdownNow():不会调用tryLock(),而是直接调用interruptWorkers();中断所有线程