併發程式設計 發布與逸出

2021-08-26 08:54:56 字數 2125 閱讀 2850

發布:物件能在當前作用域之外的**中使用。

發布方式:

1、物件引用儲存到其他地方

2、public方法返回物件引用

3、引用傳遞到其他方法

某個不該發布的物件發布,這種情況成為逸出

封裝使得程式的正確性進行分析變得可能,這也是封裝最重要的意圖,

構造物件的過程中不要讓this引用逸出,常見的是在建構函式中啟動乙個執行緒。啟動執行緒後,新的執行緒能夠訪問該物件的this,新的執行緒可能會操作乙個尚未構造完成的物件,

執行緒封閉是實現執行緒安全最簡單的方式,也是使用較多較好的方式,過多的共享物件會使得系統難以維護。

ad-hoc執行緒封閉

維護執行緒封閉性完全有程式設計師承擔

棧封閉執行緒封閉的特例,只有通過區域性變數才能訪問物件,

區域性變數的固有屬性就是封閉在直線的執行緒中,他們位於執行執行緒的棧中,而棧是執行緒獨佔的。

threadlocal類

能將值與物件關聯,threadlocal通常用於防止對可變的單例項物件或全域性變數共享

某個頻繁執行的操作需要乙個臨時物件,避免每次執行都重新分配該物件,可以使用threadlocal

不變性不變物件一定是執行緒安全的

滿足不可變物件條件:

1、物件建立後狀態不能修改

2、所有域都是final

3、物件是正確建立的,this沒有逸出

public holder holder;

public void initialize()

public class holder

public void assertsanity()

}

根據之前的可見性問題,其他執行緒看到的holder物件將處於不一致的狀態 。

由於沒有使用同步來確保holder物件對其他執行緒可見,因此holder被稱為未被正確發布-

為正確發布的物件有兩個問題:

1、除了發布物件的執行緒外,其他執行緒可以看到holder是乙個失效值。

可在不需要額外同步情況下安全發布,

狀態不可修改

所有域都是final型別

正確構造

可變物件必須通過安全的方式發布,這意味著發布和使用該物件的執行緒都必須使用同步。

要安全發布乙個可變物件,物件的引用及物件的狀態必須同時對其他執行緒可見。乙個正確的構造物件可通過下面幾個方式發布,

1、在靜態初始化函式中初始化乙個物件引用

2、將物件的引用儲存到volatile型別的域或者atomicreferance物件中

3、將物件的引用儲存到某個正確構造物件的final型別域中

4、將物件的引用儲存到乙個由鎖保護的域中

發布乙個競態構造物件,最簡單安全的方式就是使用靜態的初始化器。

public staitc holder holder = new holder();

靜態初始化器有jvm在類的初始化階段執行。在jvm內部存在同步機制,這種方式是可以安全發布的

將物件的引用儲存到乙個由鎖保護的域中這條,我們可以安全的發布arraylist,hashmap這些不安全的物件。

concurrency庫容器類提供了多種安全發布保證:

1、將鍵值對放入hashtable(不怎麼用了)、synchronizedmap或者concurrentmap中

2、某個元素放入vector、copyonwritearraylist、copyonwritearrayset、synchronizedlist或synchronizedset中

3、blockqueue、concurrentlinkedqueue中,

future、exchanger也可以安全發布

物件在安全發布後不會修改,沒有同步的情況下,安全發布是足夠的,當物件引用對所有訪問該物件的執行緒可見,物件發布時的狀態對於所有執行緒也是可見的,並且如果物件狀態不會改變,足以保證安全訪問。

事實不可見物件,不僅可以簡化開發,還可以減少同步提高效能。

物件在構造後會發生修改,那麼安全發布只是確保發布當時狀態的可見性,對於可變物件不僅發布物件時使用同步,而且在每次物件訪問時同樣使用同步確保後續操作的可見性。

物件的發布取決於其可變性:

不可變物件可以任意安全發布

事實不可變物件必須通過安全機制發布。

可變物件不僅要通過安全方式發布,而且必須是執行緒安全的或由鎖保護的。

併發程式設計 08安全發布物件之發布與逸出

小結 發布物件 使乙個物件能夠被當前範圍之外的 所使用,日常開發中比較常見的比如通過類的非私有方法返回物件的引用,或者通過公有的靜態變數發布物件等都屬於發布物件 物件逸出 首先需要明確的是物件逸出是一種錯誤的發布方式。當乙個物件還沒有構造完成時,就使它被其他執行緒所見。package com.art...

多執行緒與併發 發布與逸出

發布 publish 乙個物件是指,使物件能夠在當前作用域之外的 中使用。當某個不應該發布的物件被發布時,這種情況就被稱為逸出 escape public static setknownsecrets 公有變數 public void initialize 上述 在initialize方法中例項化了...

併發程式設計實踐筆記 物件的共享之發布與逸出

發布 物件的發布是指 使物件能夠在當前作用域之外的 中使用。例如在乙個非私有的方法中將私有屬性的物件引用直接返回。逸出 是指當某個不該被發布的物件被發布出去。例如,如果在物件完成構造之前就將其發布出去,就會破壞執行緒安全性。警惕this引用逸出。當從物件的建構函式中發布物件的時候,只是發布了乙個未構...