android 线程池源码解析
来源:互联网 发布:光盘刻录软件nero 编辑:程序博客网 时间:2024/05/22 10:56
先从俩个概念说起
线程池核心的接口其实是Executor,它有一个execute方法,这个方法的实现在ThreadPoolExecutor中。在ThreadPoolExecutor源码中我们常常能看到这么俩个变量:ctl,worker。
ctl
ctl是什么呢?ctl在源码里的解释是:The main pool control state, ctl, is an atomic integer packing two conceptual fields:
1.workerCount, indicating the effective number of threads
2.runState, indicating whether running, shutting down etc
也就是说ctl是一个原子变量 atomic integer,它将workerCount和runState这俩个值打包在该原子变量里。并且用某种方法打包成一个int值。
workerCount:有效线程的数量,可能会与实际值有所偏差
runState:各个线程的运行状态生命周期,包含:
RUNNING: Accept new tasks and process queued tasks(接收新任务,也执行队列里的任务)
STOP: Don’t accept new tasks, don’t process queued tasks,and interrupt in-progress tasks(不接收,不执行任务,并且中断运行中的任务)
TIDYING: All tasks have terminated, workerCount is zero,the thread transitioning to state TIDYING will run the terminated() hook method(所有任务都结束了,workerCount为0,调用terminated()方法)
TERMINATED: terminated() has completed(terminated()方法调用完成)
转换如下:
* RUNNING -> SHUTDOWN
* On invocation of shutdown(), perhaps implicitly in finalize()
* (RUNNING or SHUTDOWN) -> STOP
* On invocation of shutdownNow()
* SHUTDOWN -> TIDYING
* When both queue and pool are empty
* STOP -> TIDYING
* When pool is empty
* TIDYING -> TERMINATED
* When the terminated() hook method has completed
worker
线程池中的一个线程就是一个Worker对象,Woker中保存着三个对象,分别为:任务要运行的线程,线程任务,完成的任务数。
/** Thread this worker is running in. Null if factory fails. */ final Thread thread; /** Initial task to run. Possibly null. */ Runnable firstTask; /** Per-thread task counter */ volatile long completedTasks;
了解了这些概念后,我们看execute方法。
execute
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); /* * Proceed in 3 steps: * * 1. 当前运行的线程量少于corePoolSize给定的线程量,则新建线程添加任务,并调用addWoker。并且addWorker中会再次检测RunState和workerCount,以防止错误添加线程。 * 2. 这种情况应该是当活动的有效线程数达到了corePoolSize,此时如果一个任务可以被添加到队列中,然后就会二次检测是否该添加新线程。(因为线程在此期间可能死去)或者我们停止接收任务了。所以需要二次检测。 * * 3.如果任务队列不能再添加任务了,就开启新线程。如果失败了,意味我们停止接收任务或线程饱和,于是拒绝接收任务。 */ int c = ctl.get(); //核心线程数小于corePoolSize,创建新线程。 if (workerCountOf(c) < corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } // 活动线程数 >= corePoolSize // runState为RUNNING && 队列未满 if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); //二次检测,判断线程状态是否为Running(可接收任务状态),不是运行状态则移除已经添加到队列里的command if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) // 这行代码是为了SHUTDOWN状态下没有活动线程了,但是队列里还有任务没执行这种特殊情况。 // 添加一个null任务是因为SHUTDOWN状态下,线程池不再接受新任务 addWorker(null, false); } // 两种情况: // 1.非RUNNING状态拒绝新的任务 // 2.队列满了启动新的线程失败(workCount > maximumPoolSize) else if (!addWorker(command, false)) reject(command); }
execute方法主要分三步走:
1.当前运行的线程量少于corePoolSize给定的线程量,则新建线程添加任务,并调用addWoker。
2.当目前活动中的线程大于corePoolSize时,先加入到任务队列当中;
3.任务队列满了再去启动新的线程,如果线程数达到最大值就拒绝任务。
- Android线程池源码解析
- android 线程池源码解析
- 线程池源码解析
- 线程池源码解析
- Android线程池(四)ThreadPoolExecutor类源码解析
- Android线程池(五)Executors类源码解析
- java线程池源码解析
- 线程池ThreadPoolExecutor源码解析
- Java 线程池源码解析
- Java线程池源码解析
- Android线程池解析
- 线程池源码解析与原理探究
- Java线程池源码解析(ThreadPoolExecutor)
- Java线程池execute()方法源码解析
- Java线程池ThreadPoolExecutor源码解析
- Android 线程本地变量<一> ThreadLocal源码解析
- Android 线程本地变量<二> ThreadLocal Values源码解析
- android源码解析(4)--如何结束运行中的分线程
- APK瘦身最佳实践(Google I/O '17)
- cogs755 山海经
- FreeBSD内核模块开发入门
- tput先对应的用法
- Spring Boot的应用正常启动与关闭
- android 线程池源码解析
- MFC下应用opencv(1):显示图片
- 05 TI ZStack协议栈的分层及设备分类
- Qt5设置应用程序图标及程序的发布
- js从定义到执行,细节分析
- 消息摘要算法-HMAC算法
- Java关键字 new
- POJ
- 【Away3D代码解读】(四):主要模块简介