共同学习Java源代码-多线程与并发-ThreadPoolExecutor类(四)

    private void advanceRunState(int targetState) {
        for (;;) {
            int c = ctl.get();
            if (runStateAtLeast(c, targetState) ||
                ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
                break;
        }

    }

这是一个赋状态值的方法

先进入一个无限for循环 

建立临时变量c 赋值为ctl的get方法返回值 这个c代表的是 当前的状态 

进入if判断 判断runStateAtLeat方法或ctl的cas方法返回true 就跳出循环

其中runStateAtLeast就是判断当前状态的数值大于等于目标状态 

ctl的cas方法是将当前状态设为 目标状态和worker数按位或的结果 也就是说cas方法赋的状态前四位是状态码 后28位是线程数 


     final void tryTerminate() {
        for (;;) {
            int c = ctl.get();
            if (isRunning(c) ||
                runStateAtLeast(c, TIDYING) ||
                (runStateOf(c) == SHUTDOWN && ! workQueue.isEmpty()))
                return;
            if (workerCountOf(c) != 0) { // Eligible to terminate
                interruptIdleWorkers(ONLY_ONE);
                return;
            }


            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                if (ctl.compareAndSet(c, ctlOf(TIDYING, 0))) {
                    try {
                        terminated();
                    } finally {
                        ctl.set(ctlOf(TERMINATED, 0));
                        termination.signalAll();
                    }
                    return;
                }
            } finally {
                mainLock.unlock();
            }
            // else retry on failed CAS
        }
    }

这个是试图关闭线程池的方法

首先进入无限循环 

获取线程池的状态 

判断如果是RUNNING状态 或 TIDYING状态以上 或SHUTDOWN状态但工作队列不为空 就结束方法 

判断如果worker数量不为0 调用  interruptIdleWorkers方法 并传入常量ONLY_ONE=true 打断其中一个持有worker的线程 然后方法返回

调用mainLock锁住当前代码块 在try块里 判断如果状态设为TIDYING 并且状态位的线程数为0 成功后 调用terminated()方法 terminated方法也包裹在一个try块了 terminated的finally块里 将状态设为TERMINATED 线程数设为0  termination的Condition调用signalAll方法唤醒所有termination等待队列的线程 实际就是执行终止工作的线程都唤醒

最后mainLick解锁


    private void checkShutdownAccess() {
        SecurityManager security = System.getSecurityManager();
        if (security != null) {
            security.checkPermission(shutdownPerm);
            final ReentrantLock mainLock = this.mainLock;
            mainLock.lock();
            try {
                for (Worker w : workers)
                    security.checkAccess(w.thread);
            } finally {
                mainLock.unlock();
            }
        }
    }

这个方法是检查关闭线程池前 每隔worker锁绑定的线程是否可以使用 

首先获取SecurityManager 

判断一旦系统的SecurityManager不为空 调用checkPermission方法 传入shutdownPerm 检查可否有关闭线程的权限

将mainLock上锁 

遍历每个worker 用SecurityManager检查每个worker的线程是否可以使用

最后mainLock解锁

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值