Как заставить поток Java ожидать вывода другого потока? - PullRequest
121 голосов
/ 14 ноября 2008

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

Однако при запуске мне нужно убедиться, что изначально поток приложения ждет, пока поток БД не будет готов (в настоящее время определяется опросом пользовательского метода dbthread.isReady()). Я не возражаю, если поток приложения блокируется, пока поток БД не будет готов.

Thread.join() не похоже на решение - поток БД завершается только при завершении работы приложения.

while (!dbthread.isReady()) {} работает, но пустой цикл потребляет много процессорных циклов.

Есть еще идеи? Спасибо.

Ответы [ 13 ]

2 голосов
/ 14 ноября 2008

Это относится ко всем языкам:

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

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

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

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

Thread-A Locks lock-a
Run thread-B
Thread-B waits for lock-a
Thread-A unlocks lock-a (causing Thread-B to continue)
Thread-A waits for lock-b 
Thread-B completes and unlocks lock-b
1 голос
/ 10 мая 2016

С

  1. join() исключено
  2. вы уже используете CountDownLatch и
  3. Future.get () уже предложен другими экспертами,

Вы можете рассмотреть другие альтернативы:

  1. invokeAll from ExecutorService

    invokeAll(Collection<? extends Callable<T>> tasks)
    

    Выполняет заданные задачи, возвращая список Фьючерсов с их статусом и результатами, когда все завершено.

  2. ForkJoinPool или newWorkStealingPool с Executors (начиная с выпуска Java 8)

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

0 голосов
/ 09 мая 2016

enter image description here

Эта идея может применяться ?. Если вы используете CountdownLatches или Semaphores работает отлично, но если вы ищете самый простой ответ для интервью, я думаю, что это применимо.

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