正如Java_author提到的,客戶端鎖定是否違反同步策略的封裝?
客戶端鎖定需要守着使用一些對象X與鎖定的客戶端代碼,X使用來保護它自己的狀態。
在下面的代碼即對象X是list
。以上說的是,使用鎖所擁有的ListHelper
類型的對象來同步putIfAbsent()
,是一個錯誤的鎖。
package compositeobjects;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ListHelper<E> {
private List<E> list =
Collections.synchronizedList(new ArrayList<E>());
public boolean putIfAbsent(E x) {
synchronized(list){
boolean absent = !list.contains(x);
if(absent) {
list.add(x);
}
return absent;
}
}
}
但是,Java的作者說,
客戶端鎖定有很多共同的類擴展,他們倆夫婦的派生類的基礎實施的行爲類。正如擴展違反實現封裝[EJ條款14]一樣,客戶端鎖定違反了對同步策略的封裝。
我的理解是,Collections.synchronizedList()
返回的嵌套類實例,也使用了list
所擁有的鎖對象。
爲什麼ListHelper
客戶端鎖定(與list
)的使用,違反了同步策略的封裝?
因爲'synchronizedList'使用自己作爲監視器,而目前情況恰好如此。如果此實現更改,您的代碼將無法正常工作。 –
@AndyTurner明白了。通過'ArrayList'監控模式是個好主意。你建議嗎? – overexchange
您知道您的實用程序類可以被['synchronizedSet'](https://docs.oracle.com/javase/8/docs/api/java/util/Collections.html#synchronizedSet(java.util。組))? –