/*** 设置是否允许核心线程idle超时后退出* */public void allowCoreThreadTimeOut(boolean value) {if (value && keepAliveTime <= 0) {throw new IllegalArgumentException("Core threads must have nonzero keep alive times");}// 判断一下新旧值是否相等,避免无意义的volatile变量更新,导致不必要的cpu cache同步if (value != allowCoreThreadTimeOut) {allowCoreThreadTimeOut = value;if (value) {// 参数值value为true,说明之前不允许核心线程由于idle超时而退出// 而此时更新为true说明现在允许了,则通过interruptIdleWorkers唤醒所有的idle线程// 令其走一遍runWorker中的逻辑,尝试着让idle超时的核心线程及时销毁interruptIdleWorkers();}}}/*** 动态更新核心线程最大值corePoolSize* */public void setCorePoolSize(int corePoolSize) {if (corePoolSize < 0) {throw new IllegalArgumentException();}// 计算差异int delta = corePoolSize - this.corePoolSize;// 赋值this.corePoolSize = corePoolSize;if (workerCountOf(this.ctl.get()) > corePoolSize) {// 更新完毕后,发现当前工作线程数超过了指定的值// 唤醒所有idle线程,让目前空闲的idle超时的线程在workerCount大于maximumPoolSize时及时销毁interruptIdleWorkers();} else if (delta > 0) {// 差异大于0,代表着新值大于旧值// We don't really know how many new threads are "needed".// As a heuristic, prestart enough new workers (up to new// core size) to handle the current number of tasks in// queue, but stop if queue becomes empty while doing so.// 我们无法确切的知道有多少新的线程是所需要的 。// 启发式的预先启动足够的新工作线程用于处理工作队列中的任务// 但当执行此操作时工作队列为空了,则立即停止此操作(队列为空了说明当前负载较低,再创建更多的工作线程是浪费资源)// 取差异和当前工作队列中的最小值为kint k = Math.min(delta, workQueue.size());// 尝试着一直增加新的工作线程,直到和k相同// 这样设计的目的在于控制增加的核心线程数量,不要一下子创建过多核心线程// 举个例子:原来的corePoolSize是10,且工作线程数也是10,现在新值设置为了30,新值比旧值大20,理论上应该直接创建20个核心工作线程// 而工作队列中的任务数只有10,那么这个时候直接创建20个新工作线程是没必要的,只需要一个一个创建,在创建的过程中新的线程会尽量的消费工作队列中的任务// 这样就可以以一种启发性的方式创建合适的新工作线程,一定程度上节约资源 。后面再有新的任务提交时,再从runWorker方法中去单独创建核心线程(类似惰性创建)while (k-- > 0 && addWorker(null, true)) {if (workQueue.isEmpty()) {// 其它工作线程在循环的过程中也在消费工作线程,且用户也可能不断地提交任务// 这是一个动态的过程,但一旦发现当前工作队列为空则立即结束break;}}}}/*** 动态更新最大线程数maximumPoolSize* */public void setMaximumPoolSize(int maximumPoolSize) {if (maximumPoolSize <= 0 || maximumPoolSize < corePoolSize) {throw new IllegalArgumentException();}this.maximumPoolSize = maximumPoolSize;if (workerCountOf(this.ctl.get())> maximumPoolSize) {// 更新完毕后,发现当前工作线程数超过了指定的值// 唤醒所有idle线程,让目前空闲的idle超时的线程在workerCount大于maximumPoolSize时及时销毁interruptIdleWorkers();}}目前为止,通过v1版本的MyThreadPoolExecutor源码,已经将jdk线程池ThreadPoolExecutor在RUNNING状态下提交任务,启动工作线程执行任务相关的核心逻辑讲解完毕了(不考虑优雅停止) 。
jdk线程池默认支持的四种拒绝策略jdk线程池支持用户传入自定义的拒绝策略处理器,只需要传入实现了RejectedExecutionHandler接口的对象就行 。而jdk在ThreadPoolExecutor中提供了默认的四种拒绝策略方便用户使用 。
经验总结扩展阅读
- 如何保护环境
- 哥哥给弟弟的生日祝福句子
- 送给自己的生日快乐句子
- 闺蜜生日快乐的祝福语
- 哪些星座善于伪装自己 不会轻易透露隐私
- 廉租房能自己装修吗 廉租房申请下来可以不住吗
- 申请廉租房需要查自己的个人征信吗 公租房与廉租房的区别在哪里
- 廉租房需要摇号吗 廉租房需要自己装修吗
- 自己手剥核桃仁怎么储存
- 我的Vue之旅 10 Gin重写后端、实现页面详情页 Mysql + Golang + Gin
