不使用關鍵字就可以使代碼線程安全的可能方法是什麼?不使用`synchronized`關鍵字的線程安全代碼?
回答
只有方法本地的變量/引用。或者確保任何實例變量都是不可變的。
不可變的實例變量是否可以接受? – duffymo 2012-04-26 09:48:25
@duffymo編輯 – NimChimpsky 2012-04-26 09:50:16
不錯 - 短而重要。 – 2016-11-18 12:16:16
如果沒有可變性,一切都是線程安全的,那麼可以通過使所有數據不可變,使您的代碼成爲線程安全的。其次,你可能想看看Java併發API,它提供了讀/寫鎖定的功能,以便在有很多讀者和一些作者的情況下執行更好。純同步關鍵字也會阻止兩位讀者。
實際上,很多方面:
- 無需同步在所有如果你沒有可變狀態。
- 如果可變狀態侷限於單個線程,則不需要同步。這可以通過使用局部變量或
java.lang.ThreadLocal
來完成。 - 您也可以使用內置同步器。
java.util.concurrent.locks.ReentrantLock
與使用塊和方法訪問的鎖具有相同的功能,並且功能更強大。
我更喜歡(2),但我不確定它是否可能在不使用'synchronized'關鍵字的情況下實現消息傳遞。我可以製作一個沒有「同步」的生產者 - 消費者隊列嗎? – 2012-04-26 10:07:17
沒關係 - 我可以通過使用java.util.concurrent.Semaphore。 – 2012-04-26 10:10:06
@MartinJames任何類似隊列和交換器的併發類都可以在沒有同步的情況下使用。 (他們使用Lock來代替)Disrupter支持不鎖定或同步的消息傳遞。 (我有一個庫,它也這樣做) – 2012-04-26 11:27:08
爲什麼你需要這樣做?
僅使用本地變量/引用不會解決大多數複雜的業務需求。 另外,如果實例變量是不可變的,它們的引用仍然可以被其他線程改變。
其中一種選擇是使用類似於SingleThreadModel的東西,但非常不鼓勵和棄用。
ü也可以看看併發API通過卡爾
「如果實例變量是不可變的,它們的引用仍然可以改變」不,它們不能 – NimChimpsky 2012-04-26 10:03:37
可以解釋。我怎麼看它是如果我有一個instanace變量String s =「xyz」,我的thread1可以改變它的引用s =「abc」;和thread2現在會得到s =「abc」 – Kshitij 2012-04-26 10:08:15
s是一個引用,它已經改變,它不是不可變的,你需要「最終字符串s」 – NimChimpsky 2012-04-26 10:11:51
上面建議保持預見性您必須確保所有訪問的可變數據由順序或處理由並行訪問的問題。
最嚴重的保護使用關鍵字。除此之外,至少有兩層可能性,每一層都有其優點。
鎖/信號燈
這些可以是非常有效的。例如,如果您的結構是由多個線程讀取的,但只能更新一個,則可能會發現ReadWriteLock
有用。
如果您選擇鎖定來匹配算法,鎖定可以更加高效。
原子能
例如使用AtomicReference
可以經常提供完全無鎖的功能。這通常可以提供巨大的好處。
原子背後的推理是讓他們失敗,但告訴你他們失敗的方式,你可以處理它。
例如,如果要更改某個值,則可以讀取該值,然後只要它仍舊是舊值就可以寫入新值。這被稱爲「比較和設置」或cas
,通常可以在硬件中實現,因此非常有效。所有你需要的是這樣的:
long old = atomic.get();
while (!atomic.cas(old, old+1)) {
// The value changed between my get and the cas. Get it again.
old = atomic.get();
}
但是,請注意,可預測性並不總是要求。
- 1. 關於產品線程安全代碼
- 2. 什麼是synchronized關鍵字的使用?
- 3. 學習Java,使用synchronized關鍵字
- 4. C++多線程 - 線程安全代碼
- 5. 在多線程環境中使用DateFormat時使用synchronized關鍵字
- 6. 關於使用QThreadStorage的線程安全
- 7. 確保代碼中的線程安全
- 8. 這是線程安全的代碼?
- 9. 此代碼是否線程安全?我怎樣才能使它線程安全?
- 10. 什麼類用於關鍵字'synchronized'?
- 11. 使「不安全」代碼塊「安全」
- 12. 關於synchronized關鍵字如何處理鎖定和線程匱乏的問題
- 13. 以下代碼是否線程安全
- 14. 這段代碼是否線程安全?
- 15. 這段代碼線程安全
- 16. 該代碼是否線程安全?
- 17. 代碼重入與線程安全
- 18. 這段Java代碼線程安全嗎?
- 19. 使用異步和DataRow的非線程安全代碼
- 20. 靜態關鍵字,狀態/實例變量和線程安全
- 21. Objective-C __block關鍵字和線程安全
- 22. 使用不安全代碼的原因
- 23. 此代碼不是線程安全的,不是嗎?
- 24. 單線程在多線程中不使用同步關鍵字
- 25. 使用線程安全的代碼執行停止單例初始化代碼
- 26. 使用線程安全或非線程安全的PHP?
- 27. 如何使線程安全,而不是線程安全
- 28. 關於線程安全
- 29. 關於線程安全
- 30. MMGR問題,代碼使用和線程安全
爲什麼關閉?它是一個很好的簡潔問題 – NimChimpsky 2012-04-26 09:55:01
@NimChimpsky我也不知道,這個問題似乎對我完全有效。這絕對是可以回答的,答案不是主觀的。 – Malcolm 2012-04-26 10:00:59