原题大致如下:定义一个变量i,使while( (i+1) == (i+1)){}能够跳出循环,并说明理由。
百度了下发现并没有这道题的讲解,于是我就来献丑啦。
经过两天的查阅资料以及测试,得出了两种可行的方法。
一、利用java对字符串拼接操作符"+"的重载
String通过运算符"+"进行拼接,会创建一个临时的StringBuilder对象进行字符串处理.
比如: String a = "abc"+1; 就相当于 String a = new StringBuilder("abc").append("1").toString();
来看StringBuilder对象的toString()方法:
可以看到toString()方法返回的是new String()在堆中创建了新的String对象,所以会跳出循环。
具体代码执行如下:
通过javap 反编译这个类的class文件,如图
红框框的部分也就验证了上面所说。
二、利用多线程来使非原子操作变成线程不安全
while((i+1) == (i+1)){}是一个比较常见的竞态条件(在并发编程中,由于不恰当的执行时序而出现不正确的结果的情况称为竞态条件)类型——"先检查后执行",即通过一个可能失效的观测结果来决定下一步动作。
先上代码:
package com.bckj;
/**
* Created by DoodleJump on 2017/6/2.
*/
public class Test {
static int i = 0;
public static void main(String[] args) {
Runnable td = new Td();
Thread td1 = new Thread(td,"thread1");
Thread td2 = new Thread(td,"thread2");
td1.start();
td2.start();
while((i+1) == (i+1)){
System.out.println("循环中");
}
System.out.println("循环结束");
System.out.println("终止其余线程");
td1.stop();
td2.stop();
}
}
class Td implements Runnable{
@Override
public void run() {
while(true){
synchronized (this) {
Test.i++;
}
}
}
}
再通过javap来看看这段代码中的while((i+1) == (i+1))的字节码
红框框的部分大致意思:
getStatic #9 //读取类变量i的值,并放入栈顶
iconst_1 //把值1放入栈顶
iadd //将栈顶的两个元素除栈并进行相加,结果放入栈顶
if_icmpne 66//比较栈顶两int型数值大小,当结果不等于0时跳转到66
这样就可以更好的理解了,我们就是通过创建新的线程在读取完第一个(i+1)的时候抢占主线程,并让i++,这样两边的(i+1)自然不相等,不过这样做的话有点看运气,毕竟线程的顺利抢占并不是每次都能如意,可能有时候可能执行一会儿时间才会跳出循环。
水平有限,就弄出这两种方法,如果有想出别的法子的,可以一起交流,共同进步!