web-dev-qa-db-ja.com

オファーとポーリングで排他的にアクセスしている場合、LinkedListはスレッドセーフですか?

リンクされたリストsamplesがあります:

_protected LinkedList<RawDataset> samples = new LinkedList<RawDataset>();
_

次のように、スレッド1のリストに要素を追加しています。

_this.samples.offer(data);
_

そして、私はそのような2番目のスレッドでそこから要素を取得しています:

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

これはスレッドセーフと見なされますか?スレッド1と2はどちらもリストを変更していますが、リストの先頭または末尾のどちらかでのみ変更を行っています。

できない場合は、Java API内のクラスをpoll/offerに付属しており、スレッドセーフであることが確実です。

前もって感謝します。

ところで:Collections.synchronizedList(new LinkedList())を使用しても、offer/pollにアクセスできません。

24
André Hoffmann

LinkedListはスレッドセーフではありません。自分でロックする必要があります。

代わりに ConcurrentLinkedQueue または LinkedBlockingDeque を試してください。ニーズに合っている場合は、スレッドセーフですが、LinkedListとは少し異なる動作です。

40
nos

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.
}
9
Benoit Courtine

LinkedListはスレッドセーフではありません。代わりに LinkedBlockingDeque を使用してください

4
nanda

これは正しい-LinkedListは同期されないため、スレッドセーフではありません。 LinkedListの新しい同期された類似、つまりConcurrentLinkedQueueまたはLinkedBlockingQueueを使用したくない場合は、次のようにLinkedListを初期化できます。

LinkedList<RawDataset> samples = (LinkedList)Collections.synchronizedList(new LinkedList<RawDataset>());
1
justadev