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

来源:互联网 发布:mac下载的软件在哪里 编辑:程序博客网 时间:2024/06/04 00:48

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


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






原创粉丝点击