当前位置:
首页 > temp > 简明python教程 >
-
简单看看ThreadPoolExecutor原理(5)
(w, completedAbruptly);
}
}
//执行清理工作
private void processWorkerExit(Worker w, boolean completedAbruptly) {
if (completedAbruptly) // If abrupt, then workerCount wasn't adjusted
decrementWorkerCount();
//获取锁,统计整个线程池完成任务的个数,由于在工作集Workers中当前的Worker已经执行完毕,就从集合中删除当前的Worker
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
completedTaskCount += w.completedTasks;
workers.remove(w);
} finally {
//释放锁
mainLock.unlock();
}
//尝试将线程池状态设置为TERMINATED,如果当前线程池状态为SHUTDOWN并且工作队列为空,或者是STOP状态,则
//可以断定当前线程池中没有活动线程,就把当前线程池状态设置为TERMINATED
//在这个方法中会调用termination.signalAll()方法唤醒一些阻塞的线程,这些阻塞的线程是由于调用了线程池
//的awaitTermination方法被阻塞的
tryTerminate();
int c = ctl.get();
//如果当前线程个数小于核心线程数量,如果是就新增一个线程
if (runStateLessThan(c, STOP)) {
if (!completedAbruptly) {
int min = allowCoreThreadTimeOut ? 0 : corePoolSize;
if (min == 0 && ! workQueue.isEmpty())
min = 1;
if (workerCountOf(c) >= min)
return; // replacement not needed
}
addWorker(null, false);
}
}
我们再看看reject是怎么执行拒绝策略的,就以默认的AbortPolicy策略为例子,其实就是抛出异常:
final void reject(Runnable command) { handler.rejectedExecution(command, this); } public static class AbortPolicy implements RejectedExecutionHandler { //无参构造 public AbortPolicy() { } //这里会直接抛出异常 public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { throw new RejectedExecutionException("Task " + r.toString() + " rejected from " + e.toString()); } }
五.shutdown方法
在最上面使用线程池的例子中,我们在最后调用了线程池的shutdown方法了,这表示当前线程池不再接收新的任务了,但是当前线程池中任务队列中还是要执行的;
public void shutdown() { //获取锁 final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { //权限检查 checkShutdownAccess(); //设置当前线程池状态为SHUTDOWN,如果当前线程池状态已经是SHUTDOWN那就直接返回 advanceRunState(SHUTDOWN); //设置所有空闲线程的中断标志 interruptIdleWorkers(); onShutdown(); // hook for ScheduledThreadPoolExecutor } finally { mainLock.unlock(); } //尝试将线程池状态设置为TERMINATED tryTerminate(); } //权限检查,由于当前线程调用了shutdown()方法,于是要先检查当前线程有没有权限关闭线程池 //如果有关闭线程池的权限,还要检查是否有中断工作线程的权限 private void checkShutdownAccess() { SecurityManager security = System.getSecurityManager(); if (security != null) { security.checkPermission(shutdownPerm); final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { for (Worker w : workers) security.checkAccess(w.thread); } finally { mainLock.unlock(); } } } //shutdown方法中设置当前线程池状态为SHUTDOWN //可以看到当线程池状态如果>=SHUTDOWN就直接返回,如果不是SHUTDOWN状态,那就CAS设置成SHUTDOWN状态 private void advanceRunState(int targetState) { for (;;) { int c = ctl.get(); if (runStateAtLeast(c, targetState) || ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c)))) break; } } //
栏目列表
最新更新
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
如何完美解决前端数字计算精度丢失与数