ThreadPoolExecutor(六)——线程池关闭之后
来源:互联网 发布:牛大哥辅助软件 编辑:程序博客网 时间:2024/06/07 04:58
上一篇主要从代码角度介绍了线程池关闭相关的方法,包括各个方法之间的逻辑关系,调用关系和产生的效果。
这一篇更多从逻辑角度上来说一下线程池在shutdown之后,原来正常的处理流程有哪些变化,既是总结也是扩展。
shutdown操作之后,首先最重要的一点变化就是线程池状态变成了SHUTDOWN。该状态是开始关闭线程池之后,从RUNNING改变状态经过的第一个状态(还有一种情况是直接进STOP,调用shutdownNow的时候),有个图画的挺好,见博客Java 7之多线程线程池 - 线程池原理(2)
从入口开始看,在这个状态变化之后,每个方法的处理流程和之前比发生了什么变化?
1.execute
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); int c = ctl.get(); if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); } else if (!addWorker(command, false)) reject(command); }
有以下几种情况:
1.如果现在状态不是RUNNING,说明要么正在SHUTDOWN要么已经SHUTDOWN完毕了,这时isRunning方法是false,会走到最后一个else if中,通过addWorker的状态来执行相应操作。addWorker下一个段落会说。2.如果现在是RUNNING操作,而且入队列成功了,然后这里需要一个double check,重新检测线程池的状态,如果不是RUNNING,而且remove成功,直接reject任务。如果remove方法失败,什么都不做(因为有其他的方法正在remove任务,比如shoutDownNow的drainQueue,purge,runWorker结束时的processWorkerExit)。
3.如果现在是RUNNING操作,如果offer失败了,说明队列满了,也执行最后一个if else,调用addWorker,这时也可能开启了SHUTDOWN操作。
2.addWorker
// Check if queue empty only if necessary. if (rs >= SHUTDOWN && ! (rs == SHUTDOWN && firstTask == null && ! workQueue.isEmpty())) return false;先看这个会返回false的判断,
3.getTask
/** * Performs blocking or timed wait for a task, depending on * current configuration settings, or returns null if this worker * must exit because of any of: * 1. There are more than maximumPoolSize workers (due to * a call to setMaximumPoolSize). * 2. The pool is stopped. * 3. The pool is shutdown and the queue is empty. * 4. This worker timed out waiting for a task, and timed-out * workers are subject to termination (that is, * {@code allowCoreThreadTimeOut || workerCount > corePoolSize}) * both before and after the timed wait. * * @return task, or null if the worker must exit, in which case * workerCount is decremented */ private Runnable getTask() { boolean timedOut = false; // Did the last poll() time out? retry: for (;;) { int c = ctl.get(); int rs = runStateOf(c); // Check if queue empty only if necessary. if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) { decrementWorkerCount(); return null; } boolean timed; // Are workers subject to culling? for (;;) { int wc = workerCountOf(c); timed = allowCoreThreadTimeOut || wc > corePoolSize; if (wc <= maximumPoolSize && ! (timedOut && timed)) break; if (compareAndDecrementWorkerCount(c)) return null; c = ctl.get(); // Re-read ctl if (runStateOf(c) != rs) continue retry; // else CAS failed due to workerCount change; retry inner loop } try { Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take(); if (r != null) return r; timedOut = true; } catch (InterruptedException retry) { timedOut = false; } } }先看注释:
4.runWorker
runWorker中调用了getTask方法,所以其相应执行结果和getTask的返回有关。比如上一个段落中说的那几种情况,线程池在SHUTDOWN状态且任务队列为空,会返回null。线程池在STOP状态也会返回null(不检查队列是否为空,因为STOP状态是shutdownNow引起的,所有task都已经被drainQueue方法移除了)。
而返回null意味着runWorker中的循环会结束,然后调用processWorkerExit方法去做一些Worker退出的相关操作。
- ThreadPoolExecutor(六)——线程池关闭之后
- ThreadPoolExecutor(五)——线程池关闭相关操作
- 【JAVA】JAVA线程池——ThreadPoolExecutor
- 深入理解java线程池—ThreadPoolExecutor
- 深入理解java线程池—ThreadPoolExecutor
- 深入理解java线程池—ThreadPoolExecutor
- 深入理解java线程池—ThreadPoolExecutor
- 深入理解java线程池—ThreadPoolExecutor
- Java多线程复习与巩固(六)--线程池ThreadPoolExecutor
- Java 并发编程(六)线程池Executors与ThreadPoolExecutor
- 跟我学Java多线程——ThreadPoolExecutor(线程池)
- java线程池学习(三) —— ThreadPoolExecutor
- Java中的线程池——ThreadPoolExecutor的原理
- Java中的线程池——ThreadPoolExecutor的使用
- java并发编程—— 线程池原理 详解 ThreadPoolExecutor
- JDK 源码解析 —— Executors ExecutorService ThreadPoolExecutor 线程池
- 跟我学Java多线程——ThreadPoolExecutor(线程池)
- Android 线程池—ThreadPoolExecutor理解与使用
- 使用IntelliJ IDEA 15和Maven创建Java Web项目(1)
- android虚拟机接收短信的广播
- eclipse更新Git项目到本地工程
- Swoole Framework 入门教程(3)-风骚的入口文件
- 非正式仿聊天界面
- ThreadPoolExecutor(六)——线程池关闭之后
- com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Use JsonReader.s
- elk工作原理
- 设计模式大杂烩之二
- linux 卸载软件
- linux中的cd命令
- 将身份证号的一部分显示为“*”号
- Android多APN同时工作原理分析
- Servlet程序开发入门(一)