ConcurrentLinkedDeque vs LinkedBlockingDeque

Мне нужно иметь потокобезопасную структуру LIFO и обнаружил, что для этого я могу использовать поточно-безопасные реализации Deque. Java 7 ввела ConcurrentLinkedDeque, а Java 6 LinkedBlockingDeque.

Если бы я использовал только неблокирующие методы в LinkedBlockingDeque, такие как addFirst() и removeFirst(), имеет ли он какое-либо значение для ConcurrentLinkedDeque?

то есть. Если вы проигнорируете аспект блокировки, существует ли какая-либо другая разница между ConcurrentLinkedDeque и LinkedBlockingDeque, кроме LinkedBlockingDeque, ограниченной?

Ответ 1

Две вещи:

1: Если бы я использовал только неблокирующие методы в LinkedBlockingDeque, такие как addFirst() и removeFirst(), имеет ли он какое-либо значение для ConcurrentLinkedDeque?

Эти методы имеют различие в отношении поведения одновременной блокировки в LinkedBlockingDeque:

public E removeFirst() {
        E x = pollFirst();
        ..
    }
 public E pollFirst() {
        lock.lock(); //Common lock for while list
        try {
            return unlinkFirst();
        } finally {
            lock.unlock();
        }
    }

Аналогично для метода addFirst. В ConcurrentLinkedDeque это поведение блокировки для обоих методов отличается и более эффективно, так как оно не блокирует весь список, а его подмножество, проверка источника для ConcurrentLinkedDeque даст вам больше ясности в этом вопросе.

2: Из javadoc ConcurrentLinkedDeque:

Остерегайтесь того, что, в отличие от большинства коллекций, метод размера НЕ является постоянная работа.

..

Кроме того, объемные операции addAll, removeAll, retainAll, containsAll, equals и toArray не гарантируются атомарно.

Выше это неверно для LinkedBlockingDeque

Ответ 2

Процитировать великий Дуг Ли () (мой акцент)

LinkedBlockingDeque vs ConcurrentLinkedDeque

Класс LinkedBlockingDeque предназначен для "стандартного" класса блокировки блокировки. Текущая реализация имеет относительно низкие накладные расходы, но относительно невысокую масштабируемость....

... ConcurrentLinkedDeque имеет почти противоположный профиль производительности, чем LinkedBlockingDeque: относительно высокие накладные расходы, но очень хорошая масштабируемость.... в параллельных приложениях не все так просто, что Deque, который является потокобезопасным, но не поддерживает блокировку. И большинство из тех, которые делают, вероятно, лучше с решениями для особых случаев.

Кажется, он предлагает вам использовать LinkedBlockingDeque, если вам не нужны функции ConcurrentLinkedDeque.

Ответ 3

ConcurentLinkedDequeue заблокирован (см. комментарии в исходном коде), в то время как LinkedBlockingQueue использует блокировку. Предполагается, что это первая эффективность

Ответ 4

Первое, что оба LinkedBlockingDeque и ConcurrentLinkedDeque оба являются потокобезопасными, но один из них зависит от вашего требования к приложениям.

Например,

LinkedBlockingDequeue: Используйте эту коллекцию, если хотите, чтобы за один раз можно использовать только один поток для ваших данных и когда вам нужно блокировать ваше приложение.

ConcurrentLinkedDeque: Это также потокобезопасная коллекция deque, если приложение многопоточно, и вы хотите, чтобы каждый из ваших потоков мог получить доступ к данным, тогда ConcurrentLinkedDequeue - лучший выбор для него.

Как и в вашем вопросе,

1. Мне нужно иметь потокобезопасную структуру LIFO,

Используйте LinkedBlockingDeque, если вы хотите, чтобы только ваши данные могли обрабатывать только один поток.

Используйте ConcurrentLinkedDeque, если вы хотите, чтобы каждый поток мог получить доступ к общим данным

2. Если вы проигнорируете блокирующий аспект, есть ли другая разница между ConcurrentLinkedDeque и LinkedBlockingDeque,

Да, есть разница, поскольку LinkedBlockingDeque использует механизм блокировки, а ConcurrentLinkedDeque это не может повлиять на производительность, когда вы хотите управлять своими данными.