[英]Client-side locking
在ListHelper
每個實例都包含自己的列表的情況下,您可以將該列表ListHelper
私有,然后在ListHelper
實例上進行同步。 我想這是一個有點構造的例子,用盡可能少的代碼來說明這一點。 IMO 名稱ListHelper
意味着我可以傳遞一個外部列表,該列表顯然可以被多個ListHelper
實例重用。
我想說的重點是:給定代碼,並且不改變list
可見性(可能會破壞其他代碼),您比當前的ListHelper
實例更好地在list
同步。
首先,我們應該了解作者的目的。 作者的目的是構建一個線程安全的List工具,它對包括putifAbsent方法在內的所有方法都是安全的。
ListHelper也可能有如下其他一些方法:
public void addList(E x)
{
list.add(x);
}
public void removeList(E x)
{
list.remove(x);
}
如果某個線程調用removeList並且第二個線程調用addList而第三個線程調用putIfAbsent,那么,因為它們是不同的鎖,所以會發生錯誤。
這里的重點是表明如果您使用同步列表,並且您想添加另一個線程安全的方法,您必須使用相同的鎖。 這里的目的是表明,如果您在輔助類中對此進行同步,但依賴列表提供的同步上的其他方法(鎖定列表實例 - 它會破壞線程安全。
是的,我們可以簡單地首先將 List< E > 對象設為私有,以使 ListHelper 類成為線程安全的。 這樣,List<E> 對象就不需要是線程安全的。
class ImprovedList<T> {
private final List<T> list;
public ImprovedList(List<T> list) {
this.list = list;
}
public synchronized boolean putIfAbsent(T x) {
boolean absent = !list.contains(x);
if (absent)
list.add(x);
return absent;
}
}
如果我們將列表設為私有,那么除了 put-if-absent 之外,您將如何利用列表的其他操作? 然后,您還必須實現列表的所有其他操作,因此要實現所有列表操作,您將使用 List 實現 ListHelper。 現在,您正在默默地走向組合模式。 由於您使用 List 接口實現了 ListHelper,所以現在它不再是 Helper 類,它變成了列表本身,因此我們可以說它是一個改進列表
class ImprovedList<T> {
private final List<T> list;
public ImprovedList(List<T> list) {
this.list = list;
}
public synchronized boolean putIfAbsent(T x) {
boolean absent = !list.contains(x);
if (absent)
list.add(x);
return absent;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.