引言
在看線程池源碼時發現了一個奇怪的用法(java.util.concurrent.ThreadPoolExecutor#addWorker),疑問來了:break,continue都懂,但是這個後面還加個retry是啥意思,前面加個retry:是幹嘛的。
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類似於goto,通常與循環放在一起,用於continue/break被retry標識的循環。(不過goto我沒用過…)
舉個栗子
小潘對大朗說:你賣炊餅一天干8小時,平均每小時能掙2文錢,我這裏需要20文錢買三氧化二砷,你什麼時候賺夠錢了再回來。大朗看着身旁美麗動人的妻子,嘿笑了兩聲挑着扁擔準備出門。“對了,3天后咱得去隔壁西門慶家串門,不管你掙沒掙夠都得回來啊!”
//一天8小時,每小時2文,問武大郎什麼時候能回家
int sum = 0;
int day = 1;
abc:
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 8; j++) {
sum += 2;
//掙夠了錢就回家
if (sum >= 20) {
break abc;
}
}
//每天1文錢開銷
sum--;
day++;
}
System.out.println(String.format("金蓮妹妹,我回家了,我總共用了%s天,掙了%s文錢", day,sum));
總結
- label標識符命名不固定,上面我命名就爲abc。
- abc標識的是外層循環,break abc指的是直接跳出外層循環。
- 如果換成continue abc;指的是:今天賺夠了錢,早早下班,明天再接着賣炊餅。
完~