2010-07-29 303 views
18

我有一個鏈表samplesLinkedList是線程安全的,當我使用offer和poll進行訪問時,它是線程安全的嗎?

protected LinkedList<RawDataset> samples = new LinkedList<RawDataset>(); 

我追加元素到列表中的線程1這樣的:

this.samples.offer(data); 

而且我從檢索它的元素在第二個線程像所以:

public RawDataset retrieveSample() { 
    return this.samples.poll(); 
} 

這是否被認爲是線程安全的?即使線程1和2都在修改列表,他們只能在列表的首部或尾部進行修改,對吧?

如果不是任何人都可以指向我的一個類,那麼在poll/offer附帶的Java API中肯定是線程安全的?

預先感謝您。

順便說一句:Collections.synchronizedList(new LinkedList())將不會給我訪問offer/poll

+1

方法'offer'和'poll'實際上declard接口'Queue',除了List接口以外,它由LinkedList實現。這就是爲什麼這些方法對Collections.synchronizedList的結果不可用。 – 2010-07-29 12:05:12

回答

31

LinkedList不是線程安全的。你必須自己鎖定。

嘗試使用ConcurrentLinkedQueueLinkedBlockingDeque而不是如果它符合您的需求,它們是線程安全的,但與LinkedList略有不同。

+0

如果我想要一個最大鏈接隊列,我應該怎麼做,這樣如果插入一個新項目並且我們達到最大值,那麼最舊的項目將被刪除(沒有阻塞,因爲沒有必要這樣做)?我需要它來記錄最近的X個事件。我應該只使用普通的LinkedList,並使用「synchronized」嗎?還是有一個很好的併發數據結構呢? – 2017-02-27 09:53:45

+0

@androiddeveloper聽起來像是一個循環隊列,你應該在這裏提問一個關於這個問題的問題,而不是爲這個老問題添加評論。 – nos 2017-02-27 10:03:13

+0

是的,我有一種感覺,這是它的名字,但有沒有內置的實現,這是線程安全的? – 2017-02-27 10:29:53

8

如果你有一個JDK,你可以看看「Collections.synchronizedList()」的源代碼。這很簡單,所以你可以創建一個專門用來獲得LinkedList和同步函數的方法的副本。

public class SynchronizedLinkedList<T> implements List<T> { 

    private LinkedList<T> list; 

    private Object lock; 

    public void add(T object) { 
     synchronized(lock) { 
      list.add(object); 
     } 
    } 

    // etc. 
} 
+2

我一般傾向於選擇現有的類來實現我自己的類。所以我會用另外兩個建議中的一個去解決。不過謝謝你。 – 2010-07-29 11:48:21

+6

爲什麼你會引入一個額外的鎖對象,如果你可以簡單地同步可變對象 - 列表本身? – 2013-01-17 19:45:43

1

這是正確的 - LinkedList不同步,因此不是線程安全的。如果你不希望使用鏈表,即的ConcurrentLinkedQueue或的LinkedBlockingQueue的更新同步的類比,你可以像這樣初始化鏈表:

LinkedList<RawDataset> samples = (LinkedList)Collections.synchronizedList(new LinkedList<RawDataset>()); 
+4

這可能適用於某些環境,但不能保證從「集合」返回的值。synchronizedList()'總是可以轉換爲'LinkedList'。一般來說,如果你必須演員,你需要重新考慮你的設計。 – 2014-05-02 01:02:19

相關問題