Параллелизм Java - Должен заблокироваться или уступить?

У меня есть несколько потоков каждый с его собственной частной параллельной очередью и всем, что они делают выполняется бесконечный цикл, получающий сообщения от него. Это могло произойти, что одна из очередей не получает сообщения сроком на время (возможно, пара секунд), и также они могли прибыть в большие пакеты, и быстрая обработка необходима.

Я хотел бы знать то, что будет самым соответствующим, чтобы сделать в первом случае: используйте блокирующуюся очередь и заблокируйте поток, пока я больше не ввел или делаю Thread.yield ()?

Я хочу иметь как можно больше ресурсов ЦП, доступных в установленный срок, поскольку количество параллельных потоков может увеличиться со временем, но также и я не хочу, чтобы обработка сообщения отстала, поскольку нет никакой гарантии того, когда поток будет перенесен для выполнения при выполнении урожая (). Я знаю, что аппаратные средства, операционная система и другие факторы играют важную роль здесь, но откладывание это и рассмотрение его от Java (JVM?) точка зрения, что было бы самым оптимальным?

6
задан Michael Myers 9 March 2010 в 20:39
поделиться

4 ответа

Всегда просто блокируйте очереди. Java блокирует очереди внутренне.

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

9
ответ дан 8 December 2019 в 14:42
поделиться

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

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

Кроме того, если в будущем появятся более совершенные алгоритмы управления потоками - например, что-то вроде Apple Grand Central Dispatch , - вы сможете преобразовать свое приложение для его использования почти без усилий.

0
ответ дан 8 December 2019 в 14:42
поделиться

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

Thread.yield () - чрезвычайно темпераментный зверь - планировщик играет большую роль именно в том, что он делает; и одна простая, но действенная реализация - просто ничего не делать.

7
ответ дан 8 December 2019 в 14:42
поделиться

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

0
ответ дан 8 December 2019 в 14:42
поделиться