Java安全發布的理解

來源:互聯網
上載者:User

標籤:java並發   發布   creat   class   enum   排序   解決方案   oca   安全   

看《Java並發編程實戰》遇到如下問題

代碼:

/**
* Created by yesiming on 16/11/11.
*/
public class Holder {
private int n;

public Holder(int n) {
this.n = n;
}

public void assertSanity() {
if(n != n) {
throw new AssertionError("This statment is false.");
}
}
}

疑問是:assertSanity() 方法中的判斷 n != n
n它怎麼就能不等於n呢,它們是同一個變數呀

解惑:設想一下情境
有2個線程 A,B
A做的操作:Holder holder = new Holder(42);
B做的操作:
if(holder != null) {
  holder.assertSantiy();
}
對於線程A的操作,jvm執行時的步驟:1.棧裡產生holder引用,2.執行建構函式,在堆裡產生Holder的記憶體空間,並且給n賦值為42,3.把holder指向堆裡產生的記憶體空間
問題是:上面的1,2,3步驟不是按照1,2,3的順序執行的,執行引擎對指令重排序後,可能會按照1,3,2的順序執行,也可能是別的順序
結果:這樣就導致當holder指向了堆裡的記憶體空間時(這時holder不是null了),但是建構函式執行尚未完成,n還沒有被賦值為42。

對於線程B的操作,assertSanity()方法編譯後的指令如下:

public void assertSanity();
flags: ACC_PUBLIC
Code:
stack=3, locals=1, args_size=1
0: aload_0
1: getfield #2 // Field n:I
4: aload_0
5: getfield #2 // Field n:I
8: if_icmpeq 21
11: new #3 // class java/lang/AssertionError
14: dup
15: ldc #4 // String This statment is false.
17: invokespecial #5 // Method java/lang/AssertionError."<init>":(Ljava/lang/Object;)V
20: athrow
21: return
LineNumberTable:
line 14: 0
line 15: 11
line 17: 21
LocalVariableTable:
Start Length Slot Name Signature
0 22 0 this Lo1/Holder;
}

注意看綠色部分的指令,
第一步:1: getfield #2 // Field n:I
取得n的值
第二部:5: getfield #2 // Field n:I
取得n的值
也就是說,在執行比較指令if_icmpeq之前,要讓比較的兩個數都進棧,然後做比較
那麼,既然要進棧2次,也就可以推匯出,當線程B操作第一步getField時,n沒有被線程A賦值,那麼這個n是0,之後,線程A修改了n的值,第二次進棧時,n的值已經是修改後的42了
這樣,就會導致棧頂2個slot中的數,一個0,一個是42,必然會導致8: if_icmpeq的結果為真

解決方案:
把n定義成final,並且在聲明Holder時,使用valetile關鍵字
final能保證Holder在構造方法執行時,不會被執行引擎重排序,也就不會出現holder指向了Holder構造產生的記憶體空間,但是構造方法沒有執行完成的情況(n沒有被賦值)
valetile保證了在外部程式中,線程A和線程B對Holder的更新狀態是隨時可見的

Java安全發布的理解

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.