32位jdk中, long 型別的變數多執行緒中賦值操作問題
package im.zxd.test;
public class LongTest {
public static long num = 0;
public static final long value1=-1L; public static final long value2=0; public static void main(String[] args) { Thread t1=new Thread(new Runnable() { public void run(){ while(true){ num=value1; } } }); Thread t2=new Thread(new Runnable() { public void run(){ while(true){ num=value2; } } }); t1.start(); t2.start(); while(true){ long value=num; if(value!=value1&&value!=value2){ System.out.println("賦值出現了 異常值"); System.out.println("二進位制:"+Long.toBinaryString(value)); System.out.println("異常值:"+value);
break; } else{ System.out.println("value"+ num); } } }
}
執行這段程式碼後,列印如下的值:
這種情況是在 32jdk 中給64 變數 long 的時候出現的問題,原因就是 32jdk 操作64變數long的時候,是兩次操作完成 的。
先給32位賦值,然後給剩下的32位賦值,當多個執行緒出現競爭的時候,會出現A執行緒賦值了一般(32位),B執行緒給另一半(32位)賦值了,就出現了 例子裡出現的情況。 前面32位是 -1的值,後32位是0的值,結果 出現了-4294967296這樣的值。
這種情況,只要保證 變數在賦值的時候,A執行緒操作完全結束後,B執行緒才進行賦值操作,這樣就可以避免這種情況。java中用
volatile 關鍵字修飾就可以解決這種問題,當然也可以加鎖來使變數的操作序列。
----------------------------閒著沒事兒 寫個例子增強記憶