线程池笔记

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小邓9907

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值