1、基本介绍
在讲解线程池ThreadPoolExecutor源码分析的时候,在addWorker(Runnable firstTask, boolean core)方法中有遇到过retry标签,作者也是第一次遇到这个标签,一时兴趣变写下这篇文章记录一下retry标签的基本使用。首先retry标签不是关键字,它是break 和 continue 的语法,是为了在多重循环中使用break和continue,用于跳出多重循环,retry标签下面必须紧跟着for或while循环体,否则编译就不会通过。
接下来看一下retry标签在ThreadPoolExecutor源码中addWorker方法中的使用情况,如下图所示:
2、示例分析
2.1 单个循环
/**
* 一个循环体
*/
private static void m0() {
retry:
for (int i = 0; i < 5; i++) {
System.out.println("i=" + i);
if(i==3){
break retry;
}
}
}
执行结果:
从执行结果来看,单个循环使用retry标签跟直接使用break没有明显的差别,接下来看看该方法编译后的class文件代码,如下所示。
private static void m0() {
for(int i = 0; i < 5; ++i) {
System.out.println("i=" + i);
if (i == 3) {
break;
}
}
}
从以上代码可知,通过编译器编译后的代码已经给我们去掉了retry标签。
2.2 多重循环
/**
* 多重循环
*/
private static void m1() {
retry:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
System.out.println("i=" + i + ",j=" + j);
if (i == 1) {
System.out.println("跳出本次循环......");
continue retry; // 跳出本次循环
}
if (i == 3 && j == 2) {
System.out.println("跳出多重循环......");
break retry; // 跳出循环
}
}
}
System.out.println("循环体执行结束......");
}
执行结果:
从执行结果来看,在 i 等于 1,j 等于 0 的时候,执行continue retry;语句跳出内层循环到retry标签处继续执行;在 i 等于 3 ,j 等于2 的时候,执行break retry;语句跳出多重循环,也就是跳过这个retry标签的循环。接下来看看该方法编译后的class文件代码,如下所示。
private static void m1() {
label30:
for(int i = 0; i < 5; ++i) {
for(int j = 0; j < 5; ++j) {
System.out.println("i=" + i + ",j=" + j);
if (i == 1) {
System.out.println("跳出本次循环......");
break;
}
if (i == 3 && j == 2) {
System.out.println("跳出多重循环......");
break label30;
}
}
}
System.out.println("循环体执行结束......");
}
从以上代码可知,通过编译器编译后的代码continue retry;语句已经被优化为break;,执行break相当于跳出内层循环。
2.3 自定义标签-多重循环
跳出多重循环的标签还可以自定义,并不是一定非得写成retry,比如下面的代码写成retryTest也是可以的。
private static void m2() {
retryTest:
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 5; j++) {
System.out.println("i=" + i + ",j=" + j);
if (i == 1) {
System.out.println("跳出本次循环......");
continue retryTest; // 跳出本次循环
}
if (i == 3 && j == 2) {
System.out.println("跳出多重循环......");
break retryTest; // 跳出循环
}
}
}
System.out.println("循环结束......");
}
执行结果:
执行结果跟2.2一致,在此不再过多赘述。接下来看看该方法编译后的class文件代码,如下所示。
private static void m2() {
label30:
for(int i = 0; i < 5; ++i) {
for(int j = 0; j < 5; ++j) {
System.out.println("i=" + i + ",j=" + j);
if (i == 1) {
System.out.println("跳出本次循环......");
break;
}
if (i == 3 && j == 2) {
System.out.println("跳出多重循环......");
break label30;
}
}
}
System.out.println("循环结束......");
}
从以上代码可知,通过编译器编译后的代码continue retry;语句已经被优化为break;,执行break相当于跳出内层循环,也是跟2.2中的代码一致。
通过对上面示例的了解,相信读者对retry标签的使用已经有一个更深层次的了解,总结一下就是,在retry标签后需要紧跟for或者while循环体,break retry; 表示要跳过这个标记的循环,continue retry; 表示从这个标记的循环继续执行。
备注:博主微信公众号,不定期更新文章,欢迎扫码关注。