簡體   English   中英

創建和加入線程時副作用的可見性

[英]visibility of side effects when creating and joining threads

當沒有同步塊和易失性變量時,一個線程執行的寫入何時對另一個線程可見? 這是一個簡化的快速排序示例:

int middle = partitionForTheFirstTime(array);

Thread t = new Thread(new Quicksorter(array, 0, middle - 1));
Thread u = new Thread(new Quicksorter(array, middle + 1, array.size - 1));

t.start()
u.start();

t.join();
u.join();

(為了簡單起見,假設兩個“工作線程”不產生任何額外的線程。)

加入這兩個線程是否保證當前線程看到它們的所有副作用?


在相關說明中,如果我在初始分區之前創建線程會發生什么?

Quicksorter a = new Quicksorter();
Quicksorter b = new Quicksorter();

Thread t = new Thread(a);
Thread u = new Thread(b);

int middle = partitionForTheFirstTime(array);

a.setParameters(array, 0, middle - 1);
b.setParameters(array, middle + 1, array.size - 1);

t.start()
u.start();

t.join();
u.join();

兩個線程能否看到partitionForTheFirstTime()引起的副作用? 換句話說,創建線程是否會產生先發生關系,還是啟動線程?

JLS 的第 17.4.5 節

從上面的定義可以得出:

  • 監視器上的解鎖發生在該監視器上的每個后續鎖定之前。
  • 對 volatile 字段(第 8.3.1.4 節)的寫入發生在對該字段的每次后續讀取之前。
  • 線程上的 start() 調用發生在已啟動線程中的任何操作之前。
  • 線程中的所有操作都發生在任何其他線程從該線程上的 join() 成功返回之前。
  • 任何 object 的默認初始化發生在程序的任何其他操作(默認寫入除外)之前。

關於start()join()的部分與您相關 - 換句話說,當您成功join() -ed 線程時,您會看到該線程中的所有操作。 如果您start()一個線程,該新線程將看到調用start()的線程中已經發生的所有操作。

編輯:另見“內存一致性錯誤”

除非您在執行 partitionForTheFirstTime() 之前執行 start(),否則兩個線程都將對相同的數據進行操作。 但是在此示例中,在將引用值傳遞給這些單獨的線程時需要小心,數組值是通過引用傳遞的,與通過值傳遞的原始值相反。 結果,兩個線程都將在同一張表上運行,這可能會導致競爭條件

暫無
暫無

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

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