Является ли LinkedList потокобезопасным, когда я обращаюсь к нему исключительно с предложением и опросом?

У меня есть связанный список samples:

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

Я добавляю элементы в список в потоке 1 следующим образом:

this.samples.offer(data);

И я извлекаю из него элементы во втором потоке, например:

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

Будет ли это считаться потокобезопасным? Несмотря на то, что потоки 1 и 2 изменяют список, они делают это исключительно либо в начале, либо в конце списка, верно?

Если это не так, может ли кто-нибудь указать мне класс в Java API, который поставляется с poll/offer и обязательно будет потокобезопасным?

Заранее спасибо.

Кстати: Collections.synchronizedList(new LinkedList()) не дает мне доступ к offer/poll.


person André Hoffmann    schedule 29.07.2010    source источник
comment
Методы offer и poll фактически объявлены в интерфейсе Queue, который реализован LinkedList в дополнение к интерфейсам List. Вот почему эти методы недоступны для результата из Collections.synchronizedList.   -  person Jörn Horstmann    schedule 29.07.2010


Ответы (4)


LinkedList не является потокобезопасным. Вам придется сделать запирание самостоятельно.

Попробуйте ConcurrentLinkedQueue или LinkedBlockingDeque вместо этого, если это соответствует вашим потребностям, они потоковые безопасно, но немного отличается от LinkedList.

person nos    schedule 29.07.2010
comment
Что мне делать, если я хочу иметь связанную очередь максимального размера, чтобы, если новый элемент был вставлен и мы достигли максимального значения, самый старый элемент был удален (без блокировки, потому что в этом нет необходимости)? Мне это нужно для журнала последних X событий. Должен ли я просто использовать обычный LinkedList и использовать для него синхронизацию? Или для этого есть хорошая параллельная структура данных? - person android developer; 27.02.2017
comment
@androiddeveloper Звучит как круговая очередь, вы должны задать вопрос здесь, в stackoverflow, о том, чтобы не добавлять комментарий к этому старому вопросу. - person nos; 27.02.2017
comment
Да, у меня было ощущение, что это было его имя, но есть ли для этого встроенная реализация, которая является потокобезопасной? - person android developer; 27.02.2017

если у вас есть 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.
}
person Benoit Courtine    schedule 29.07.2010
comment
Обычно я предпочитаю существующие классы реализации собственных. Так что я пойду с одним из двух других предложений. Но все равно спасибо. - person André Hoffmann; 29.07.2010
comment
Зачем вводить дополнительный объект блокировки, если можно просто синхронизироваться с изменяемым объектом — списком — самим собой? - person Konrad Reiche; 17.01.2013

Нет LinkedList не является потокобезопасным. Вместо этого используйте LinkedBlockingDeque.

person nanda    schedule 29.07.2010
comment
или LinkedBlockingQueue? - person rogerdpack; 29.09.2015

Это правильно - LinkedList не синхронизируется и, следовательно, не является потокобезопасным. Если вы не хотите использовать более новые синхронизированные аналоги LinkedList, а именно ConcurrentLinkedQueue или LinkedBlockingQueue, вы можете инициализировать LinkedList следующим образом:

LinkedList<RawDataset> samples = (LinkedList)Collections.synchronizedList(new LinkedList<RawDataset>());
person justadev    schedule 31.07.2013
comment
Это может работать в некоторых средах, но нет гарантии, что значение, возвращаемое из Collections.synchronizedList(), всегда можно преобразовать в LinkedList. В общем, если вам приходится отливать, вам нужно переосмыслить свой дизайн. - person Matt Quigley; 02.05.2014