簡體   English   中英

在Java中發生的事先機制

[英]Happens-before mechanism in Java

我在Java中遇到過關於先發生機制的問題。 這是一個例子:

public class MyThread extends Thread {

        int a = 0;
        volatile int b = 0;

        public void run() {


            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            read();
        }

        public void write(int a, int b) {
            this.a = a;  
            this.b = b;
        }

        public void read() {
            System.out.println(a + " " + b);
        }


    }

這是事先發生的明顯例子,這是足夠安全的,正如我所知道的那樣。 a將正確獲得新值,因為它在b初始化之前。 但重新排序是否意味着安全性得不到保證? 我在說這個:

public void write(int a, int b) {
    this.b = b;
    this.a = a;//might not work? isn't it?
}

UPD主線程:

public class Main {

    public static void main(String[] args) throws InterruptedException {

        MyThread t = new MyThread();
        t.start();
        t.write(1, 2);


    }
}

使b變為volatile並且在write值設置為b后將write值設置為b a保證:

  1. 如果b之前讀a ,然后
  2. a的值不會超過之前寫入b時的值。

即,到寫入b和從讀b充當同步點,或圍欄,這意味着無論被寫入a寫之前b將從讀取后可讀b (如果a被寫入一次以上,以下寫入可能會或可能不會顯示)。

但是,您的代碼現在不安全。 read ,您有以下表達式:

a + " " + b

在Java中, 表達式從左到右進行計算 這意味着, a會前進行評估b 因此,它是完全可能的讀a會看到一個舊值a ,同時的讀b將看到一個新的值b 假如你有b之前讀a ,之間發生,之前關系b的寫入和讀取會覆蓋在寫a ,並從讀a 現在,它沒有。

至於write重新排序操作 - 這將明顯消除b的排序保證對a操作過度a ,即使read首先讀取b然后讀取a

為了可視化事物,只給出bvolatile

當前代碼不保證在 - 的操作順序 -

write a                         read a
write b --> happens before -->  read b

重新排序write使用給定的讀取不會為了a ,以及-

                                read a
write b --> happens before -->  read b
write a

即使給定的read是固定的, a不會被責令b -

write b --> happens before -->  read b
write a                         read a

唯一安全的做法是保持當前write並修復read -

write a
write b --> happens before -->  read b
                                read a

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM