2009-07-22 18 views
4

請通過我應該鎖定哪些對象上,當我路過一個集合<Foo>成一個單獨的類?

foos = Collections.synchronizedList(new ArrayList<Foo>(10)); 

當連接#start()被調用時,它會創建輪詢的一個實例是指UML

連接類的構造函數初始化它FOOS成員(在經過FOOS參考到輪詢的構造函數)&輪詢開始(輪詢是一個Runnable)。

問題:本輪詢線程將基於外部事件列表添加到&刪除對象。定期的客戶將調用連接#快照()檢索列表。由於Poller中的實現將執行檢查以避免添加期間的重複,因此它不是線程安全的。

例如輪詢#運行的FPGA實現

if(_foos.indexOf(newFoo) == -1) 
{ 
    _foos.add(newFoo); 
} 

我能在連接以及輪詢同步到爲了線程安全的嗎?

+0

你可以在你的問題中嵌入圖像,你不需要使用外部鏈接。 – 2011-10-17 06:07:08

回答

0

你可能會從snapshot()返回一個新的列表:

public List<Foo> snapshot() { 
    return new ArrayList<Foo>(foos); 
} 

假設你正在返回一個「快照」,似乎確定我該列表是保證了最新的僅在它返回的那一刻。

如果您希望客戶添加/刪除foos中的成員,那麼您可能需要將這些操作公開爲Connection上的方法。

+0

客戶並不是無法在快照中添加/刪除。 – 2009-07-22 04:09:53

1

我會看看的CopyOnWriteArrayList作爲在上面的例子中的ArrayList的替代品。這樣,你就不需要,因爲你有一個線程安全集合開箱上的任何內容同步,可以這麼說......

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/CopyOnWriteArrayList.html

從API的CopyOnWriteArrayList是...

ArrayList的線程安全變體,其中所有可變操作(添加, 集合等)均由 實現,並創建基本 數組的新副本。

注:如果遍歷的數量超過集合的添加/更新數量,這只是一個可行的解決方案。是這樣嗎?

1

存在使用接口和匿名內部類清潔溶液。

連接類中添加以下內容:

public static interface FooWorker { 
    void onFoos(List<Foo> list); 
} 

public synchronized void withFoosSafely(FooWorker worker) { 
    worker.onFoos(foos); 
} 

輪詢類執行以下操作:

public void doWork() { 
    connection.withFoosSafely(new FooWorker() { 
     public void onFoos(List<Foo> list) { 
       /// add, remove and change the list as you see fit 
       /// everything inside this method is thread-safe 
     } 
    }); 
} 

它需要多一點額外的代碼(沒有倒閉但在Java),但它保證了線程安全,並且確保客戶在將來不需要關注鎖定 - 較少的潛在錯誤。

0

也許我沒有得到這一點,似乎Connection#snapshot應該this同步(或_foos)等做管理Connection._foosPoller代碼塊。

我錯過了什麼?

+0

Poller是一個獨立的類,它不是Connection的內部類! – 2009-07-23 01:44:10

相關問題