Java併發編程實戰讀書筆記(一、線程安全性)

1.無狀態的對象一定線程安全,因爲沒有共享狀態,題目都在訪問不同的實例。

2.當某個計算的正確性取決於多個線程的交替執行時序時,就會發生競態條件

3.當無狀態類中添加一個狀態時,如果該狀態由線程安全對象來管理,那這個類仍是線程安全的。當添加多個變量時不一定,因爲多個狀態變量之間往往會存在約束,當一個變量更新時需要在同一個原子操作中對其他變量進行同時更新,而線程安全類只能保證對單個變量的操作是安全的。

加鎖機制

1.內置鎖

java提供一種內置的鎖機制來支持原子性:同步代碼塊。以關鍵字Sychronized來修飾的方法是一種跨整個方法體的同步代碼塊,其鎖就是方法調用所在的對象。若A線程嘗試獲得一個B線程持有的鎖,A線程必須等待或者阻塞。

2.重入

內置鎖是可重入的,線程可以獲取已經由自己持有的鎖。這意味鎖的操作粒度是“線程”而不是“調用”。重入鎖一種實現方法是關聯一個獲取計數值和所有者線程。

以下代碼中子類和父類中都獲取子類的鎖

public class Widget {
    public synchronized void doSomething() {...}
}
 
public class LoggingWidget extends Widget {
    @Override
    public synchronized void doSomething() {
        System.out.println(...);
        super.doSomething();
    }
}

關於@guardedby註釋

1、@GuardedBy( "this" ) 受對象內部鎖保護
2、@GuardedBy( "fieldName" ) 受 與fieldName引用相關聯的鎖 保護。
3、@GuardedBy( "ClassName.fieldName" ) 受 一個類的靜態field的鎖 保存。
4、@GuardedBy( "methodName()" ) 鎖對象是 methodName() 方法的返值,受這個鎖保護。
5、@GuardedBy( "ClassName.class" ) 受 ClassName類的直接鎖對象保護。而不是這個類的某個實例的鎖對象。

當有執行時間較長的計算或者可能無法快速完成的操作時,一定不要持有鎖。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章