2012-03-12 41 views
2

如果我有隻有一個這樣的單一語句同步?

public class NumberClass{ 
    int number; 

    public int getNumber() { 
     return number; 
    } 
    ... 
} 

和多個線程同時訪問這個方法聲明getter方法,我一定要同步,這個方法還是因爲它只有一個說法,沒有必要?

回答

7

我必須同步這個[get]方法,或者它沒有必要,因爲它只有一個語句?

它與1個或多個語句無關。這取決於該值是否已在另一個線程中更新,以及是否希望所有線程都看到一致的值。

如果在thread1中更新了number字段,則thread2可能會根據更新的同步方式獲取原始值或新值。要正確發佈該值,set和get方法需要​​。

如果你只是想分享的int值,則標誌着number場爲volatile將工作或使用AtomicInteger共享多個線程之間的值可靠地可能更適合。

private volatile int number; 

或使用:

private AtomicInteger number = new AtomicInteger(); 
+0

我也有類似的問題有關同步[這裏](https://stackoverflow.com/questions/47783712/do-not-share-same-socket-between-two-threads-at-the-same-time /)在socket對象上使用同步,我試圖看看我是否可以通過其他有效的方式完全擺脫同步?想看看你能不能幫忙。 – john 2017-12-16 07:30:24

+0

他做了@DavidSchwartz。他在評論中提到了他的問題。 – Gray 2017-12-18 00:47:47

4

,也可能是同步的發言是個好主意。原因在於,根據規範,每個線程都允許緩存自己版本的變量。要證明它,看看this answer

其他選項是

  • 使變量波動:

    volatile int number; 
    
  • 或使用AtomicInteger從java.util.concurrent包:

    AtomicInteger number; 
    

作爲一個側面說明:如果number已經long型的,甚至不是一個讀取變量的本來原子(一個線程可以重寫的變量在讀的中間值) 。請參閱Java語言規範的Chapter 17.7: Non-atomic Treatment of double and long

1

您需要內存屏障,否則其他線程不能保證能看到「正確」的值(意思是任何明確指定給number的值)。

爲了解決這個問題,聲明number作爲finalvolatile構件,或從一個塊​​訪問它。

聲明的數量,與其他一些答案相反,的一個考慮因素。你不需要原子性(因爲它是一個單一的聲明),所以使用​​可能是矯枉過正。如果值發生變化,請使用volatile,如果沒有,請使用final。如果您有多個需要以原子方式顯示的語句,則​​將是唯一的選項。