2010-07-29 58 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

相关问题