线程同步 线程安全_同步装饰器来替换线程安全类
線程同步 線程安全
您知道什么是線程安全嗎? 如果沒有,下面是一個簡單的示例。 所有類都必須是線程安全的,對嗎? 并不是的。 其中一些必須是線程安全的? 又錯了。 我認為它們都不必是線程安全的,而它們都必須提供同步的裝飾器。
阿拉丁(1992),羅恩·克萊門茨和約翰·馬斯克
讓我們從一個示例開始(順便說一下,它是mutable ):
class Position {private int number = 0;@Overridepublic void increment() {int before = this.number;int after = before + 1;this.number = after;} }您如何看待-它是線程安全的嗎? 該術語指的是當同時由多個線程使用時,此類的對象是否將正確運行。 假設我們有兩個線程在同一個對象position ,并在完全相同的時刻調用其方法increment() 。
我們期望兩個線程結束時整數的number等于2,因為它們每個都會遞增一次,對嗎? 但是,這極有可能不會發生。
讓我們看看會發生什么。 在兩個線程中,啟動時, before等于0 。 然后after將設置為1 。 然后,兩個線程會做this.number = 1 ,我們將結束與1的number ,而不是預期2 。 看到問題了嗎? 在設計中存在此類缺陷的類不是線程安全的 。
最簡單,最明顯的解決方案是使我們的方法synchronized 。 這樣可以保證無論有多少線程同時調用它,它們都會按順序而不是并行進行:一個線程接一個線程。 當然,這將花費更長的時間,但是它將防止該錯誤的發生:
class Position {private int number = 0;@Overridepublic synchronized void increment() {int before = this.number;int after = before + 1;this.number = after;} }保證無論有多少線程都不會中斷的類稱為線程安全 。
現在的問題是:我們是否必須使所有類都成為線程安全的,或者只使其中某些類成為線程安全的? 使所有類都無錯誤似乎更好,對嗎? 為什么有人想要一個可能在某個時候破裂的物體? 好吧,不完全是。 請記住,涉及性能問題; 我們通常沒有多個線程,并且我們始終希望我們的對象盡可能快地運行。 線程間同步機制肯定會使我們慢下來。
我認為正確的方法是開設兩個班級。 第一個不是線程安全的,而另一個是同步的decorator ,它看起來像這樣:
class SyncPosition implements Position {private final Position origin;SyncPosition(Position pos) {this.origin = pos;}@Overridepublic synchronized void increment() {this.origin.increment();} }現在,當我們需要position對象是線程安全的時,我們可以使用SyncPosition裝飾它:
Position position = new SyncPosition(new SimplePosition() );當我們需要一個簡單的簡單位置而沒有任何線程安全性時,我們可以這樣做:
Position position = new SimplePosition();我認為使類功能既豐富又線程安全是違反了那個著名的單一責任原則的 。
順便說一句,這個問題非常接近防御性編程和驗證程序之一。
您可能還會發現與這些相關的帖子有趣: 您如何使用InterruptedException? ; 為什么InputStream設計錯誤 ; 限制Java方法執行時間 ; 如何實現一個迭代適配器 ; 通過驗證裝飾器進行防御性編程 ;
翻譯自: https://www.javacodegeeks.com/2017/01/synchronized-decorators-replace-thread-safe-classes.html
線程同步 線程安全
總結
以上是生活随笔為你收集整理的线程同步 线程安全_同步装饰器来替换线程安全类的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 徜组词 徜字如何组词
- 下一篇: forge开发_使用Forge,Wild