runWorker方法对中断设置的理解

背景

在阅读线程池代码的时候看到runWorker里面有个很迷的操作:先把线程池中断位重置掉,然后再设置中断位,这里记录一下自己的理解。

runWorker

final void runWorker(Worker w) {
        ...
                if ((runStateAtLeast(ctl.get(), STOP) ||
                     (Thread.interrupted() &&
                      runStateAtLeast(ctl.get(), STOP))) &&
                    !wt.isInterrupted())
                    wt.interrupt();
      ...     
    }

这里有两种情况:
1、如果线程池状态是stop并且当前线程是没有设置中断位的,则给当前线程设置中断位。
2、如果线程池的状态不是stop,使用Thread.interrupted()判断当前线程的中断状态,如果是true,再继续判断线程池的状态是否为stop如果是stop,则给当前线程设置中断。

第二种情况看起来做了多此一举的操作,当初一看的时候让人把注意力放到了runStateAtLeast(ctl.get(), STOP)这个操作上了,因为只要为true就不会执行(Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))这个操作,如果为false就已经跳出了这个if语句了,似乎无论如何都不会执行它。

再上一段代码:

public List<Runnable> shutdownNow() {
        List<Runnable> tasks;
        final ReentrantLock mainLock = this.mainLock;
        mainLock.lock();
        try {
            checkShutdownAccess();
         1、   advanceRunState(STOP);
         2、    interruptWorkers();
            tasks = drainQueue();
        } finally {
            mainLock.unlock();
        }
        tryTerminate();
        return tasks;
    }

线程池执行这个方法会把线程池的状态变为stop,不接受新的任务,不再执行队列里面的任务,还会给线程设置中断位(设置中断位不是说立即把线程正在执行的任务也停了,只是说正在执行的任务如果遇到了阻塞就把它停了,所以正常状态下线程还是会把最后一个任务执行完毕才退出)
这里的1和2分别是设置线程池状态为stop和设置线程的中断位,但是这里因为是多线程环境,主线程正在把线程池的状态设置为stop,工作线程给自己设置中断位。当指令重排序的时候可能会使得线程池的状态还没有设置完,工作线程会先设置了中断位。
因此就出现了runWorker里面的操作,如果中断位的设置早于stop的设置,就把中段位清理掉,重新设置。
出现这样的操作应该是要严格保证,stop–>中断设置,这样的顺序吧,stop才是大佬,大佬没动小弟不敢动。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值