2013-05-21 3 views
2

У меня есть простое приложение java, которое вычисляет простые числа до определенного заданного пользователем номера и выводит цифры. Я построил на нем четыре отдельных потока, которые повторяются через 4 отдельных диапазона чисел. Как только все 4 потока завершили свои итерации, я хочу напечатать окончательный ArrayList.Как я могу запланировать заявление печати после завершения 4 независимых потоков?

В настоящее время я получаю исключение ConcurrentModificationException, потому что после того, как я запустил 4 потока, следующая строка кода является оператором печати, который пытается распечатать ArrayList, который в этот момент изменяется хотя бы одним из все еще активных потоки.

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

ответ

2

Используйте CountdownLatch. Javadoc для этого класса рассказывает, как иметь

  1. Основной поток создает защелку с количеством потоков.
  2. Основной поток запускает все рабочие потоки.
    1. Каждая нить имеет ссылку на защелку.
    2. Он подсчитывает фиксацию при завершении работы.
  3. Основной поток ожидает защелкой отсчет до 0.
  4. Основной поток делает задание печати.
+0

Спасибо, он отлично работает. Я очень рад, что узнал об этом, поскольку я могу предвидеть использование этого в будущем для реальных проектов. – fvgs

+0

Вы могли бы даже поставить задачу печати в свою собственную нить, поэтому основной поток может сделать что-то еще. –

0

Если вы используете java.util.concurrent.BlockingQueue, каждый поток может put() элемент в очереди блокировки, когда он будет готов.

Перед операцией печати код может сделать take() из очереди блокировки и только после того, как take() вернул один раз для каждого потока. Нить печати будет блокироваться на take(), в то время как нет ничего, что можно было бы предпринять. Это гарантирует, что печать не начнется, пока все потоки не закончатся.

4

Использовать CountDownLatch с инициализацией до 4; нить печати awaits защелка, а рабочие потоки вызовут countdown на защелку до их завершения.

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

+0

Спасибо, отлично работает! – fvgs