ThreadPoolExecutor中addWorker,continue retry和break retry是什么意思

今天看ThreadPoolExecutor的代码,其中有一个addWorker的函数,里面有个retry的标签,从来没遇到过这种用法。来深入探究一下。

先看一下addWorker的代码。

private boolean addWorker(Runnable firstTask, boolean core) {
        retry:
        for (;;) {
            int c = ctl.get();
            int rs = runStateOf(c);

            // Check if queue empty only if necessary.
            if (rs >= SHUTDOWN &&
                ! (rs == SHUTDOWN &&
                   firstTask == null &&
                   ! workQueue.isEmpty()))
                return false;

            for (;;) {
                int wc = workerCountOf(c);
                if (wc >= CAPACITY ||
                    wc >= (core ? corePoolSize : maximumPoolSize))
                    return false;
                if (compareAndIncrementWorkerCount(c))
                    break retry;
                c = ctl.get();  // Re-read ctl
                if (runStateOf(c) != rs)
                    continue retry;
                // else CAS failed due to workerCount change; retry inner loop
            }
        }
...
}

我们先来猜测一下,retry不是java中的关键字,这应该类似标签的一种写法,看起来有点像goto;break retry可能是跳出到retry标签处(继续执行retry标签下的循环,保留最外层循环的变量临时值),continue retry直接跳出标签(不管标签中有几层循环),继续执行其他代码。实际是不是这样呢?

show me the demo code!

public class RetryDemo {

    public static void main(String[] args) {
        int count = 0;
        retry:
        for (int i=0; i<3; i++) {
            for (int j=0; j<5; j++) {
                count++;
                if (count == 4) {
                    continue retry;
                }
                System.out.print(count + " ");
            }
        }

    }
}

输出结果:
1 2 3 5 6 7 8 9 10 11 12 13 14


public class RetryDemo {

    public static void main(String[] args) {
        int count = 0;
        retry:
        for (int i=0; i<3; i++) {
            for (int j=0; j<5; j++) {
                count++;
                if (count == 4) {
                    break retry;
                }
                System.out.print(count + " ");
            }
        }

    }
}

输出结果:
1 2 3

聪明的你,看明白为什么输出会是这样么?

再来解释一遍, break label直接跳出到标签处,不再执行循环代码;continue label,只是结束本轮循环,跳转到标签处,继续下一轮循环(本质上与单层循环的break和continue类似)。

写到这里,那提个问题,如果是三层for循环的标签,输出结果是什么呢?

public class RetryDemo {

    public static void main(String[] args) {
        int count = 0;
        retry:
        for (int i=0; i<3; i++) {
            for (int k=0; k<2; k++) {
                for (int j = 0; j < 5; j++) {
                    count++;
                    if (count == 4) {
                        continue retry;
                    }
                    System.out.print(count + " ");
                }
            }
        }

    }
}

输出结果
1 2 3 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24


public class RetryDemo {

    public static void main(String[] args) {
        int count = 0;
        retry:
        for (int i=0; i<3; i++) {
            for (int k=0; k<2; k++) {
                for (int j = 0; j < 5; j++) {
                    count++;
                    if (count == 4) {
                        break retry;
                    }
                    System.out.print(count + " ");
                }
            }
        }

    }
}
输出结果
1 2 3

可以发现,break retry输出的结果仍是1 2 3,continue retry,只是提前结束了一轮的循环,下一轮循环仍然会继续。大师把代码写成这样是经典,我们就不建议把代码写成这样了,可读性太差。

那addWorker这段代码到底什么意思呢?大师是用CAS无锁的方式,增加线程数,因为是CAS无锁,那就有可能增加线程数失败,此时continue 到retry标签处重试,重新尝试CAS无锁的方式增加线程数;haha,如果运气比较好,直接增加线程数成功,那就bread retry好了,继续执行其他逻辑代码。

你真的懂了么?最好把demo代码复制下来本机调试一下!欢迎留言沟通!

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值