2014-09-13 87 views
0

我正在學習多線程,並且有一個小問題。 當我在線程之間共享某個變量(ArrayList,或其他像double,float)時,它是否應該由讀/寫中的同一個對象來提取?我的意思是,當1個線程設置變量值時,是否可以同時讀取任何問題?還是應該被相同的對象鎖定,並強制線程等待閱讀,直到它被另一個線程更改?Java。讀,寫,單獨同步

+0

ArrayList不同步。所以,如果有多個線程寫入它將會出現問題。此外,每個線程不保證最新值。 – TheLostMind 2014-09-13 13:57:03

+0

您可以檢查集合的線程安全版本,例如ConcurrentSet,ConcurrentMap或CopyOnWriteArrayList。 – px5x2 2014-09-13 13:59:46

+0

我推薦閱讀:http://docs.oracle.com/javase/tutorial/essential/concurrency/sync.html我相信很多即將到來的問題也會在那裏得到解答。 – Fildor 2014-09-13 14:05:51

回答

1

對共享狀態的所有訪問必須由相同的鎖保護,無論是讀取還是寫入。讀操作必須等待寫操作釋放鎖。作爲一種特殊情況,如果您想要在同步塊內完成一次讀取或寫入操作,那麼您可以省去同步塊並將該變量標記爲易失性。

0

短:這取決於。

更長: 對於每種不同的場景都有很多「正確答案」。 (這使編程變得有趣)

  • 要讀取的值是否必須是「最新的」?
  • 要寫的價值是否讓所有讀者都知道?
  • 如果兩條線程寫入,我應該注意任何競態條件嗎?
  • 如果讀取舊的/舊的值,會有什麼問題嗎?
  • 什麼是正確的行爲?
  • 它真的需要它是正確的嗎? (是的,有時你不照顧好)

TL;博士

例如,不是所有的線程編程需「總是正確的」

  • 有時你權衡正確性與性能(例如日誌或進度計數器)
  • 有時讀取舊值就好了
  • 有時您最終需要更正(例如,在map-reduce中,沒有人或同步是正確的,直到全部完成)
  • 在某些情況下,每個時刻(例如,您的銀行賬戶餘額)
  • 只寫一次,只讀不要緊。
  • 某些時候線程在複雜情況下。
  • 有時許多小的,獨立的鎖跑的快,但有時平坦全球鎖更快
  • 和許多許多其他可能的情況下

這裏是我的建議:如果你正在學習,你應該的事「爲什麼要我需要一把鎖?「和「爲什麼鎖可以幫助不同的情況?」 (不僅僅是教科書給出的樣本),「如果失敗會失敗,或者如果鎖定失蹤會發生什麼?」

0

如果所有線程正在讀取,則不需要同步。

如果一個或多個線程正在讀取並且有一個或多個線程正在寫入,您需要以某種方式進行同步。如果收藏品很小,則可以使用​​。您可以添加​​塊來訪問集合,​​訪問集合或使用併發線程安全集合(例如Vector)的方法。

如果你有一個龐大的收藏,你想允許共享閱讀,但獨家寫作,你需要使用ReadWriteLock。在這裏看到的JavaDoc和你想的例子是什麼確切的描述:

ReentrantReadWriteLock

注意,這個問題是很常見的,有很多關於這個站點類似的例子。