筆試題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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章