笔试题while((i+1) == (i+1)){}引发的思考

原题大致如下:定义一个变量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)自然不相等,不过这样做的话有点看运气,毕竟线程的顺利抢占并不是每次都能如意,可能有时候可能执行一会儿时间才会跳出循环。


水平有限,就弄出这两种方法,如果有想出别的法子的,可以一起交流,共同进步!






发布了27 篇原创文章 · 获赞 7 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章