Подтвердить что ты не робот

Неужели плохо использовать опрос в Java?

У меня есть несколько ArrayLists, которые работают как очереди данных. Каждая из очередей связана с отдельным потоком, который проверяет, имеет ли этот ArrayList некоторые данные в нем.

 while (array.size == 0) {
    // nothing
 }

 // do stuff with one element of the array
 // remove element from array
 // and call the loop again

Я сделал аналогичные вещи во встроенном системном программировании, но безопасно ли это использовать в Java? Забота об отходах технологической мощности, итерации вокруг этого, в то время как цикл очень быстрый.

Это можно решить, добавив Thread.sleep(100) и проверить каждые 100 мс, а затем снова - более медленное время отклика.

Вопрос: мне нужно добавить этот сон, или я не должен беспокоиться об этом?

Любые предложения по более безопасной/лучшей системе для проверки новых данных в массивах?

4b9b3361

Ответ 1

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

И ожидание, как вы описываете, потребляет ресурсы процессора без необходимости.

Поскольку вам, похоже, нужна очередь, почему бы вам не использовать ее, например ArrayBlockingQueue. Он имеет take метод, который блокирует, не потребляя циклы процессора, до тех пор, пока элемент не будет добавлен в очередь. И это потокобезопасно.

Ответ 2

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

Вы должны использовать wait/notify или какой-либо другой механизм сигнализации для приостановки потока и разбудить его только при необходимости.

Переходя к более продвинутым конструкциям, существуют специализированные структуры данных для моделей-производителей-потребителей, например BlockingQueue (выберите реализацию):

Очередь, которая дополнительно поддерживает операции, ожидающие очереди стать непустым при извлечении элемента и дождаться места становятся доступными в очереди при хранении элемента.

Ответ 3

Как насчет использования somehting как блокирующей очереди, которая была выпущена в java 5. Я думаю, что это рекомендуется сейчас по wait/notify, которое может стать довольно сложным. Я использовал его, и он работает хорошо.

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/BlockingQueue.html

Ответ 4

java.lang.ArrayList не является потокобезопасным вообще. Для целей массового обслуживания полезно использовать BlockingQueue. Он блокирует вызов потока, если очередь пуста, не потребляя процессор. Вы можете использовать ArrayBlockingQueue или LinkedBlockingQueue или другую реализацию очереди в соответствии с вашими потребностями.

Даже вы можете реализовать его с помощью wait and notifyAll, но всегда рекомендуется использовать BlockingQueue.

Ответ 5

Вместо использования ArrayList вы можете использовать коллекцию Concurrent, скажем, например, ArrayBlockingQueue

ArrayBlockingQueue<YourObject> theQueue;
while(true) {
  YourObject o = theQueue.take();
 //process your object
}

В другом месте, где вы заполняете свою очередь, вы просто выполняете

theQueue.add(theElement);

Поток, ожидающий объекты, будет "спать" до тех пор, пока не появится элемент. Метод add пробудит поток потребления.

Подробнее об этом классе читайте здесь: http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ArrayBlockingQueue.html

Ответ 6

Без сна ваши потоки будут работать так же быстро, как они могут, и получить доступ к ArrayList, возможно, в большинстве случаев без каких-либо результатов.

Я бы рекомендовал реализовать шаблон прослушивателя/наблюдателя. Если возможно, попросите продюсера, который заполняет ArrayList, уведомляет соответствующие потоки об изменениях. Таким образом, вы переключитесь с поведения опроса на поведение push.

Не уверен, что это выполнимо в вашей архитектуре, вам потребуются дополнительные объяснения в вашей системе.

Ответ 7

Что такое опрос и какие проблемы с ним?

Процесс проверки состояния повторно до тех пор, пока он не станет истинным, известен как опрос.

Опрос обычно выполняется с помощью циклов, чтобы проверить, является ли конкретное условие истинным или нет. Если это так, то предпринимаются определенные действия. Этот отход многих циклов процессора и делает реализацию неэффективной. Например, в классической задаче массового обслуживания, когда один поток создает данные, а другой потребляет его.

Как многопоточная многопоточность Java решает эту проблему?

Чтобы избежать опроса, Java использует три метода: wait(), notify() и notifyAll().

Все эти методы относятся к классу Object как final, так что все классы имеют их. Они должны использоваться только в синхронизированном блоке.

wait(). Он сообщает вызывающему потоку отказаться от блокировки и перейдет в режим сна, пока какой-либо другой поток не войдет в тот же монитор и не вызовет notify().

notify(). Пробуждает один единственный поток, который называется wait() на том же самом объекте. Следует отметить, что вызов notify() фактически не отменяет блокировку ресурса.

notifyAll() - он просыпает все потоки, которые вызывали wait() на одном и том же объекте.

ArrayList не является потокобезопасной коллекцией. Используйте ArrayBlockingQueue.

Класс ArrayBlockingQueue