java中goto作为关键字,没有实际用处,在C/C++/汇编语言中经常使用,用于跳转至指定位置
虽然Java中的goto不起作用,但Java 中同样可以定义标签(当然Java中标签的设计不是为了goto),使用标识符加冒号的形式,例如retry:
Java 中的标签是为循环设计的,是为了在多重循环中方便的使用 break 和 coutinue 而设计的,这也是Java中唯一用到标签的地方。
正是由于这个原因,Java 的标签只能定义在三种循环 (for() {}, do{} while(), while() {}) 的开始位置,否则编译器会报告说找不到标签。
在循环前面加上标签,就好像给循环起了个名字。而后在循环中使用 break 或者 continue 语句的时候,就可以带上这个标签做为参数,指明跳出 (break) 或者继续 (continue)标签对应的哪个循环,如break retry;
、continue retry;
。
public class retryLearn {
static void retryContinue() {
System.out.println("执行retryContinue:");
int i = 0, j = 0;
retry:
for (i = 0; i < 2; i++) {
for (j = 0; j < 5; j++) {
System.out.println(j);
if (j == 3) {
continue retry;
}
}
}
System.out.printf("after loop, i = %d, j=%d", i, j);
}
static void retryBreak() {
System.out.println("执行retryBreak:");
int i = 0, j = 0;
retry1:
for (i = 0; i < 2; i++) {
for (j = 0; j < 5; j++) {
System.out.println(j);
if (j == 3) break retry1;
}
}
System.out.printf("after loop, i = %d, j=%d\n", i, j);
}
static void whileLabel() {
System.out.println("执行whileLabel:");
int i = 0;
int j = 0;
whileLabel:
while (i++ < 10) {
while (j < 10) {
System.out.println(j);
if (j == 6) break whileLabel;
++j;
}
}
System.out.printf("after loop, i = %d, j=%d\n", i, j);
}
public static void main(String[] args) {
retryContinue();
System.out.println("***********************");
retryBreak();
System.out.println("***********************");
whileLabel();
}
}
以retryBreak函数举例,当第二层for循环中j的值是3的时候,执行break retry1
语句,
而retry1这个标签标记的是第一层循环,也就是说对最外层循环执行break,所以当在i的值为0,j的值为3的时候跳转两层嵌套的for循环
源码中的使用:ThreadPoolExecutor#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
}
}
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;
}