当前位置:
首页 > temp > 简明python教程 >
-
简单看看ThreadPoolExecutor原理(6)
设置所有空闲线程的中断标志
private void interruptIdleWorkers() {
interruptIdleWorkers(false);
}
private void interruptIdleWorkers(boolean onlyOne) {
//加锁,同时只有一个线程可以调用shutdown方法设置中断标志
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//遍历所有的worker中的线程,如果线程没有中断然后成功获取worker自己的锁,就中断该线程
//注意,worker实现了AQS,如果worker能够获取自己的锁,说明该线程没有在执行任务,就可以设置中断
//而有的worker中的线程正在执行的任务的线程,则不会中断
for (Worker w : workers) {
Thread t = w.thread;
if (!t.isInterrupted() && w.tryLock()) {
try {
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}
六.shutdownNow方法
这个方法和shutdown的区别就是,前者会中断线程池中所有的线程,不管是正在执行任务的还是空闲的,而且还会把阻塞队列中没来得及执行的任务丢弃;
public List<Runnable> shutdownNow() { List<Runnable> tasks; final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { //权限检查 checkShutdownAccess(); //将线程池状态设置为STOP advanceRunState(STOP); //中断线程池中所有线程 interruptWorkers(); //将阻塞队列中任务都抛弃 tasks = drainQueue(); } finally { mainLock.unlock(); } tryTerminate(); return tasks; } //中断线程池中所有线程 private void interruptWorkers() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { //这里直接遍历,所有的worker都调用interruptIfStarted方法,这个方法就在下面 for (Worker w : workers) w.interruptIfStarted(); } finally { mainLock.unlock(); } } void interruptIfStarted() { Thread t; //如果Worker的线程不为空,而且该线程不是中断状态,就把该线程中断 if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) { try { t.interrupt(); } catch (SecurityException ignore) { } } } //将阻塞队列中任务都抛弃,很简单的集合操作 private List<Runnable> drainQueue() { BlockingQueue<Runnable> q = workQueue; ArrayList<Runnable> taskList = new ArrayList<Runnable>(); q.drainTo(taskList); if (!q.isEmpty()) { for (Runnable r : q.toArray(new Runnable[0])) { if (q.remove(r)) taskList.add(r); } } return taskList; }
七.总结
重要的方法就是这几个,其实所谓的线程池就是巧妙的利用了一个Integer类型的原子变量来记录线程池状态和线程池中线程数量,通过线程池状态来控制线程的执行,每个Worker线程可以执行多个任务,其实就是在runWorker中的循环:while (task != null || (task = getTask()) != null) ,在这里不断的轮询拿到当前Worker中的第一个任务或者从任务队列中取到任务,然后会去执行;
栏目列表
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数