Параллелизм Java - должен блокировать или уступать? - PullRequest
6 голосов
/ 09 марта 2010

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

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

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

Ответы [ 4 ]

9 голосов
/ 09 марта 2010

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

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

7 голосов
/ 09 марта 2010

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

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

0 голосов
/ 16 марта 2010

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

0 голосов
/ 10 марта 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...