1.线程池
1.1ThreadPoolExecutor executor= new ThreadPoolExecutor(
corePoolSize:1,//核心线程个数
maximumPoolSize:2,//最大线程数 包括核心线程和非核心
keepAliveTime:500,//非核心线程空闲时间
TimeUnit.SECONDS,//单位
new LinkedBlockingDeque<>(),//阻塞队列
new ThreadFactory() { //线程工厂 自己写线程工厂创建线程池利于设置参数和名字
@Override
public Thread newThread(Runnable r) {
Thread t=new Thread®;
t.setName(“测试”);
return t;
}
},
new ThreadPoolExecutor.AbortPolicy() //拒绝策略 多于线程池容量如何操作 1.异常2.主线程自己执行,副线程不执行3.除去阻塞队列第一个4.什么都不操作
);
executor.execute(new Runnable() {
@Override
public void run() {
System.out.println(“嘿嘿嘿”);
}
});
1.2线程工厂作为副线程来创建线程池
2.线程池执行过程
4.线程池状态
4.1属性ctl
//ctl本质是一个int类型数值
private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
//Integer.SIZE=32, COUNT_BITS=29
//ctl表现两个参数:一个表示线程池状态前三位 一个int32位 后29位表现工作线程个数
private static final int COUNT_BITS = Integer.SIZE - 3;
private static final int CAPACITY = (1 << COUNT_BITS) - 1;
//00000000 00000000 00000000 00000001->
//00100000 00000000 00000000 00000000->
//00011111 11111111 11111111 11111111
//表示工作线程的最大数 包括核心线程和非核
// runState is stored in the high-order bits
//线程池5种状态
private static final int RUNNING = -1 << COUNT_BITS;//111
private static final int SHUTDOWN = 0 << COUNT_BITS;//000
private static final int STOP = 1 << COUNT_BITS;//001
private static final int TIDYING = 2 << COUNT_BITS;//010
private static final int TERMINATED = 3 << COUNT_BITS;//011
/**计算当前线程池状态如:
*/
private static int runStateOf(int c) { return c & ~CAPACITY; }
//计算当前线程池的工作线程个数
private static int workerCountOf(int c) { return c & CAPACITY; }
private static int ctlOf(int rs, int wc) { return rs | wc; }
4.2线程池五个状态图:
4.2.1 shutdown方法
4.2.2stop即 shutdownnow
4.2.3过渡状态 tidying 过渡状态执行tryTermianate
4.2.4销毁线程池 termainated 需要重写 termainated :
4.3核心方法execute-提交线程即 执行流程源码
源码分析:
public void execute(Runnable command) {
//判断是否空
if (command == null)
throw new NullPointerException();
//1.创建核心线程获取ctl
int c = ctl.get();
//判断判断工作线程个数是否少于核心线程个数
if (workerCountOf© < corePoolSize) {
if (addWorker(command, true))
//如果核心线程数够就返回true
return;
//添加到核心线程失败的线程需要重新获取
c = ctl.get();
}
//2.若创建核心线程失败则添加到队列
//且先判断线程池是否running
//若处于running则添加到队列
if (isRunning© && workQueue.offer(command)) {
//成功添加到队列的情况下
int recheck = ctl.get();
//再次确认是不是running 不是就移除
if (! isRunning(recheck) && remove(command))
//不是running 执行拒绝
reject(command);
//判断工作线程是不是0 而队列有任务 会没人处理队列的任务
else if (workerCountOf(recheck) == 0)
//添加非核心空任务 来处理队列的任务
addWorker(null, false);
}
//添加到队列失败情况下,添加到非核心线程
else if (!addWorker(command, false))
//添加到非核心失败,执行拒绝策略
reject(command);
}
4.4addworker方法-添加工作线程
源码分析:
private boolean addWorker(Runnable firstTask, boolean core) {
retry: //跳出for外循环标识
//外层for
for (;;) {
int c = ctl.get(); //获取ctl
int rs = runStateOf(c); //拿到线程池状态
//判断是不是running、如果不是就继续判断任务是不是可以处理
// Check if queue empty only if necessary.
//判断状态是否为shutdown且任务为空且工作队列不为空 就要处理工作队列
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
//只要不是running,不处理新任务
return false;
//内层for 如果不进去外层if就会
//获取当前工作线程
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY || //判断工作线程是否大于最大
wc >= (core ? corePoolSize : maximumPoolSize)) //如果核心线程,判断是否大于corepoolsize,如果不是 是否大于非核心最大maxinumpoolsize 达到最大返回false
return false;
//csa方式,对工作线程+1 跳出外层 cas乐观锁 重点:内存地址、预期值、修改的值、自旋、缺点:大并发的情况下,反复自旋、只能保证单个变量原子性,多个共同联系的变量不能保证、aba问题(版本号)
if (compareAndIncrementWorkerCount(c))
break retry;
//失败 有并发重新获取
c = ctl.get(); // Re-read ctl
//判断线程池状态是否一致
if (runStateOf(c) != rs)
//并发导致线程池状态改变,重新判断状态 v,jhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}