2017-03-06 44 views
1

目前,我正在學習Java集合上Java tutorial oracle也碰到下面的段落一個unsychronized Collection對象,它包含一些數據,要同步的包裝,但不想引用原始對象

這些方法返回每個由指定集合備份的同步(線程安全)Collection。爲了保證串行訪問,必須通過返回的集合完成對後備集合的訪問,全部。保證這一點的簡單方法不是保留對後備集合的引用。使用以下技巧創建同步收集。

List<Type> list = Collections.synchronizedList(new ArrayList<Type>()); 

我只是在想,我要打開收藏的這種情況下(發生什麼事,如果我有一個尚未進行同步和包含一些數據集(後盾集合)的一個實例,後備集合)轉換爲同步集合,但不希望保留對後備集合的引用。這怎麼能做到?可能嗎?如果是的話,這是人們通常會做的事情嗎?

+1

如果您打算改變集合的狀態,爲什麼不把它的一個副本第一? –

+1

當然,你可以包裝一個現有的集合。 *最好不要持有對後備集合的引用,因爲這可以確保它不會被意外修改。 – shmosel

+4

你的問題不清楚..你可以得到一個新的清單,並容易地轉儲舊的 –

回答

1

爲了保證您不保留對後備集合的引用,請退出引用的範圍。

換句話說,聲明對塊內的支持數組的引用,並確保引用只有Collections.synchronizedList()方法。當該塊退出時,引用將丟失,並且您可以確定只有同步包裝引用了後備集合。

這不是一種常用的方法,但只要在包裝後不對備份集合進行任何更改,它就不會導致併發問題。但是,它可能會引起你的同事的一些論點,他們知道引用的習語是安全的,但不確定你的創新。這可能是通過包裝器添加元素而不是後備收集的足夠好的理由。

下面是一個例子:

class MyObj { 

    private final List<Type> list; 

    MyObj(/* Some arguments that control initial list contents */) { 
    List<Type> tmp = new ArrayList<>(); 
    tmp.add(...); 
    list = Collections.synchronizedList(tmp); 
    } /* Reference to `tmp` is lost, safety is ensured. */ 

} 
相關問題