Is LinkedList thread-safe when I'm accessing it with offer and poll exclusively?
Asked Answered
D

4

28

I have a linked list samples:

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

I'm appending elements to the list in thread 1 like this:

this.samples.offer(data);

And I'm retrieving elements from it in a second thread like so:

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

Would this be considered as thread-safe? Even though thread 1 and 2 are both modifying the list they only do so on either the head or the tail of the list exclusively, right?

If it isn't can anyone point me to a class in the Java API that comes with poll/offer and is sure to be thread-safe?

Thank you in advance.

BTW: Collections.synchronizedList(new LinkedList()) won't give me access to offer/poll.

Detached answered 29/7, 2010 at 11:33 Comment(1)
Methods offer and poll are actually declard in interface Queue, which is implemented by LinkedList in addition to the List interfaces. That is why these methods are not available on the result from Collections.synchronizedList.Bakery
T
49

LinkedList is not thread safe. You'd have to do the locking yourself.

Try ConcurrentLinkedQueue or LinkedBlockingDeque instead if it fits your needs, they are thread safe but slightly different behavior than LinkedList.

Twirl answered 29/7, 2010 at 11:38 Comment(3)
What should I do, if I want to have a max sized linked queue, so that if a new item is inserted and we reached the max, the oldest one will get removed (no blocking, because there is no need for this) ? I need it for a log of the last X events. Should I just use the normal LinkedList, and use "synchronized" on it? Or is there a nice concurrent data structure for this?Demagogic
@androiddeveloper That sounds like a circular queue, you should ask a question here on stackoverflow about that not add a comment to an this old question.Twirl
Yes I had a feeling this was its name, but is there a built in implementation for this, that's thread-safe?Demagogic
G
9

if you have a JDK, you can look at the source code of "Collections.synchronizedList()". It is simple, so you can create a copy of this method specialized to get both LinkedList and synchronization functionnalities.

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.
}
Glanville answered 29/7, 2010 at 11:41 Comment(2)
I generally tend to prefer existing classes over implementing my own. So I'll go with one of the other two suggestions. But thank you anyway.Eucaine
Why do you introduce an additional lock object if you can simply synchronize on the mutable object—the list—itself?Exaction
B
4

No LinkedList is not thread safe. Use LinkedBlockingDeque instead

Brey answered 29/7, 2010 at 11:38 Comment(1)
or LinkedBlockingQueue?Harleyharli
C
1

That is correct - LinkedList is not synchronized and thus not thread safe. If you do not want to use the newer synchronized analogies of LinkedList, namely, ConcurrentLinkedQueue or LinkedBlockingQueue, you can initialize LinkedList like this:

LinkedList<RawDataset> samples = (LinkedList)Collections.synchronizedList(new LinkedList<RawDataset>());
Camara answered 31/7, 2013 at 21:39 Comment(1)
This may work in some environments, but there is no guarantee that the value returned from Collections.synchronizedList() can always be cast to a LinkedList. In general, if you have to cast, you need to rethink your design.Molliemollify

© 2022 - 2024 — McMap. All rights reserved.