簡體   English   中英

如果一個簡單的寫是在一個同步塊中完成的,那么在另一個同步塊中的讀是一致的嗎?

[英]If a simple write is done inside a synchronized block , then a read in another synchronized block is consistent?

一個線程寫入變量的值,另一個線程讀取它,以防兩個操作都包含在同步塊中,但都定義在不同的對象上,如下所示。

private Object o1 = new Object();
private Object o2 = new Object();
private int x = 0;
...
synchronized(o1){
    x = 10;//write (simple atomic write) inside the synchronized block so value is flushed to main memory 
}
...
synchronized(o2){
     System.out.println(x);// read inside the synchronized block so read from main memory and not from thread cache.
}

Q1。 是否保證read與x的最新值一致?

另一種情況

private Object a = new Object();
private Object b = new Object();
private int p = 0;
...
synchronized(a){
    p = p + 1;
}
....
synchronized(b){
    System.out.println(p);
}

Q2。 由於p = p+1不是原子的,因此在這種情況下我們可能會遇到數據不一致的情況。 但是對於Q1。 這種情況下,因為寫入是簡單且原子的,並且在同步塊中完成,因此在這種情況下我們具有一致性。

如果我的理解正確,請幫助我。

Q1。 是否保證read與x的最新值一致?

不,因為它們在不同的事情上是同步的。

在同步塊的結束和同一監視器上同步的塊的開始之間存在先行關系。

如果監視器不同,則沒有這種關系。

您可以在語言規范JLS 17.4.5 (強調我的)中找到它:

從上面的定義可以得出:

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

Q2。 由於 p = p+1 不是原子的,因此在這種情況下我們可能會遇到數據不一致的情況。 但是對於Q1。 這種情況下,因為寫入是簡單且原子的,並且在同步塊中完成,因此在這種情況下我們具有一致性。

你沒有一致性。 請參閱問題 1 的答案。

synchronized塊,除了鎖定之外,確保內部讀取的值是相關的並從主 memory 中獲取,甚至在塊釋放之前,所有更改的數據都會傳輸到主 memory。

暫無
暫無

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

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