Executor框架集
图
ExecutorService
juc.ExecutorService继承自Executor接口
ThreadPoolExecutor
成员变量:ctl:
// 表示两种含义:
// ①:workerCount:worker计数,表示正在处理中的任务
// ②:runState:运行状态,共5种见下表
// Integer值分32位,前3位是runState,后29位是workerCount
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
运行状态值
运行状态 | 十进制 | 二进制 | 说明 | 备注 |
---|---|---|---|---|
RUNNING | -1<<29 | 111000...000000 | 运行中 | 二进制为补码表示 |
SHUTDOWN | 0<<29 | 000000...000000 | 关闭,不再接受新任务,但仍然会处理排队任务 | 正数的原码,反码,补码均相同 |
STOP | 1<<29 | 001000...000000 | 停止,不接受新任务及排队任务,中断处理中的任务 | |
TIDYING | 2<<29 | 010000...000000 | 整理,所有任务终止,workerCount归0进入该状态 | 之后将调用terminal()钩子方法 |
TERMINATED | 3<<29 | 011000...000000 | 终止,terminal()已执行完成 |
更多细节还待学习...
问
核心线程数与最大线程数怎么配?
IO密集型任务:cpu核心数*2
为什么是这个数?
理想线程数 = ((CPU运算时间+IO等待时间) / CPU运算时间) * CPU核心数,CPU和IO时间相等时就是2倍CPU核心数
CPU密集型任务:cpu核心数+1,即:Runtime.getRuntime().availableProcessors()+1
为什么是cpu核心数+1?
《Java并发编程实战》一书中给出的原因是:即使当计算(CPU)密集型的线程偶尔由于页缺失故障或者其他原因而暂停时,这个“额外”的线程也能确保 CPU 的时钟周期不会被浪费。
线程池参数可通过相应的set方法动态修改,任务队列大小不支持动态修改,但可自定义阻塞队列来实现(容量大小不使用final修饰,提供set方法)
当修改最大线程数时如果新只小于当前值,则只会回收闲置线程
线程池被创建后里面有线程吗?如果有的话,有什么方法对线程池进行预热吗?
线程池被创建后如果没有任务过来,里面是不会有线程的。如果需要预热的话可以调用下面的两个方法:
// 启动全部核心线程,返回启动的数量
public int prestartAllCoreThreads()
// 启动一个核心线程,如果所有的
public boolean prestartCoreThread()
核心线程数会被回收吗?需要什么设置?
核心线程数默认是不会被回收的,如果需要回收核心线程数,需要调用下面的方法:
// allowCoreThreadTimeOut 该值默认为 false
public void allowCoreThreadTimeOut(boolean value)
标签:...,000000,核心,任务,线程,CPU
From: https://www.cnblogs.com/z-dk/p/16952938.html