Как использовать ConcurrentLinkedQueue?

Вот официальный ответ от Qt-JIRA:

«Вы получаете доступ к своим m_connectionParams из двух разных потоков без блокировки. Основной поток записывает его в connectToEmulatorService (), а рабочий поток читает его в connectToEmulatorServiceImpl (). Если основной поток записывает снова, в то время как рабочий поток только читает предыдущую итерацию, вы получаете сбой. Это наиболее очевидная проблема.

Однако, даже если вы заблокировали мьютекс для доступа для m_connectionParams, это все равно будет небезопасно. Вариант, который у вас есть, это внутренне QJSValue. Чтобы преобразовать это в карту, мы должны вызвать глубоко в движке JavaScript, создать области и взаимодействовать с кучей JavaScript. любой другой JavaScript выполняется одновременно в другом потоке, у вас проблемы.

Просто извлеките QVariantMap из основного потока и передайте его вашему функтору в качестве параметра. "

Итак, иметь копию QVariant недостаточно ... это где-то глубоко внутри источников Qt.

91
задан P̲̳x͓L̳ 30 March 2014 в 16:13
поделиться

5 ответов

Нет, методы не должны синхронизироваться, и Вы не должны определять методы; они уже находятся в ConcurrentLinkedQueue, просто используют их. ConcurrentLinkedQueue делает всю блокировку и другие операции, в которых Вы нуждаетесь внутренне; Ваш производитель (производители) добавляет данные в очередь, и Ваши потребители опрашивают относительно него.

Первый, создайте свою очередь:

Queue<YourObject> queue = new ConcurrentLinkedQueue<YourObject>();

Теперь, где бы вы ни были создавая Ваши объекты производителя/потребителя, передачу в очереди, таким образом, они должны где-нибудь поместить свои объекты (Вы могли использовать метод set для этого, вместо этого, но я предпочитаю делать такого рода вещь в конструкторе):

YourProducer producer = new YourProducer(queue);

и:

YourConsumer consumer = new YourConsumer(queue);

и добавляют материал к нему в Вашем производителе:

queue.offer(myObject);

и вынимают материал в Вашем потребителе (если очередь будет пуста, то опрос () возвратит пустой указатель, так проверьте его):

YourObject myObject = queue.poll();

Для большего количества информации см. РЕДАКТИРОВАНИЕ Javadoc

:

, Если необходимо заблокировать ожидание очереди, чтобы не быть пустыми, Вы, вероятно, хотите использовать LinkedBlockingQueue и использовать взятие () метод. Однако LinkedBlockingQueue имеет максимальную способность (значения по умолчанию к Целому числу. MAX_VALUE, который является более чем двумя миллиардами), и таким образом может или может не быть соответствующим в зависимости от Ваших обстоятельств.

, Если у Вас только есть один материал помещения потока в очередь и другой материал вынимающего потока из очереди, ConcurrentLinkedQueue является, вероятно, излишеством. Это больше для того, когда у Вас могут быть сотни или даже тысячи потоков, получающих доступ к очереди одновременно. Ваши потребности будут, вероятно, удовлетворены при помощи:

Queue<YourObject> queue = Collections.synchronizedList(new LinkedList<YourObject>());

А плюс этого - то, что это соединяет экземпляр (очередь), таким образом, можно синхронизироваться на очереди для обеспечения атомарности составных операций (как объяснил Jared). Вы не МОЖЕТЕ сделать этого с ConcurrentLinkedQueue, поскольку все операции СДЕЛАНЫ, не соединяя экземпляр (использующий java.util.concurrent.atomic переменные). Вы НЕ должны будете делать этого, если Вы захотите заблокироваться, в то время как очередь пуста, потому что опрос () просто возвратит пустой указатель, в то время как очередь пуста, и опрос () является атомарным. Проверьте, чтобы видеть, возвращает ли опрос () пустой указатель. Если это делает, ожидает (), то попробовало еще раз. Никакая потребность заблокировать.

Наконец:

Честно, я просто использовал бы LinkedBlockingQueue. Это - все еще излишество для Вашего приложения, но разногласия - это, будет хорошо работать. Если это не достаточно производительно (ПРОФИЛЬ!), можно всегда пробовать что-то еще, и это означает, что Вы не должны иметь дело ни с КАКИМ синхронизируемым материалом:

BlockingQueue<YourObject> queue = new LinkedBlockingQueue<YourObject>();

queue.put(myObject); // Blocks until queue isn't full.

YourObject myObject = queue.take(); // Blocks until queue isn't empty.

Все остальное - то же. Помещенный , вероятно не заблокируется, потому что Вы, вероятно, не поместите два миллиарда объектов в очередь.

151
ответ дан wandermonk 24 November 2019 в 06:45
поделиться

Это в основном дубликат другого вопроса .

Вот раздел того ответа, который относится к этому вопросу:

Делают я должен сделать свою собственную синхронизацию, если я использую java.util. ConcurrentLinkedQueue?

Атомарные операции на параллельных наборах синхронизируются для Вас. Другими словами, каждый отдельный вызов очереди гарантируется ориентированный на многопотоковое исполнение без любого действия с Вашей стороны. То, что не , гарантировало ориентированный на многопотоковое исполнение, любые операции, которые Вы выполняете на наборе, которые являются неатомарными.

, Например, это ориентировано на многопотоковое исполнение без любого действия с Вашей стороны:

queue.add(obj);

или

queue.poll(obj);

Однако; неатомарные вызовы очереди не автоматически ориентированы на многопотоковое исполнение. Например, следующие операции не автоматически ориентированы на многопотоковое исполнение:

if(!queue.isEmpty()) {
   queue.poll(obj);
}

, Что последний не ориентирован на многопотоковое исполнение, поскольку очень возможно, что между временем isEmpty назван и опрос времени называют, другие потоки добавят или удалят объекты из очереди. Ориентированный на многопотоковое исполнение способ выполнить это похож на это:

synchronized(queue) {
    if(!queue.isEmpty()) {
       queue.poll(obj);
    }
}

Снова... атомарные вызовы очереди автоматически ориентированы на многопотоковое исполнение. Неатомарные вызовы не.

33
ответ дан Community 24 November 2019 в 06:45
поделиться

Используйте , опрос для получения первого элемента, и добавляет для добавления нового последнего элемента. Вот именно, никакая синхронизация или что-либо еще.

6
ответ дан Hank Gay 24 November 2019 в 06:45
поделиться

ConcurentLinkedQueue является очень эффективным, ожидают/блокируют бесплатная реализация (см. javadoc для ссылки), таким образом, не только Вы не должны синхронизироваться, но и очередь ничего не заблокирует, таким образом будучи фактически с такой скоростью, как не синхронизируемой (не ориентированный на многопотоковое исполнение) один.

2
ответ дан siddhadev 24 November 2019 в 06:45
поделиться

Просто используйте его, поскольку Вы были бы непараллельный набор. Параллельное [Набор], классы обертывают регулярные наборы так, чтобы Вы не думали о синхронизирующемся доступе.

Редактирование: ConcurrentLinkedList не является на самом деле просто оберткой, а скорее лучшей параллельной реализацией. Так или иначе Вы не должны волноваться о синхронизации.

1
ответ дан Ben S 24 November 2019 в 06:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: