原題大致如下:定義一個變量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)自然不相等,不過這樣做的話有點看運氣,畢竟線程的順利搶佔並不是每次都能如意,可能有時候可能執行一會兒時間纔會跳出循環。
水平有限,就弄出這兩種方法,如果有想出別的法子的,可以一起交流,共同進步!