Причины использования Thread.join()
В последнее время мне сказали старшие разработчики не использовать Thread.join(), чтобы дождаться окончания другого потока. Я также видел несколько таких вопросов о том, как SO просит альтернатив присоединиться.
В моих исследованиях я не мог найти ничего плохого в join(). На самом деле он широко используется.
Итак, я хотел бы знать, почему не использовать join()? Что с этим не так? Поддерживает ли он плохое программирование или архитектуру?
Ответы
Ответ 1
Нет ничего плохого в join()
. Это так же хорошо, как и получается.
Однако, почему вы не должны архивировать приложение, чтобы полагаться на объединения. В Java основной абстракцией для запуска задач больше не является Thread. Это Executor
. То есть вы переносите параллельные задачи как Callable
и просто отправляете его в Executor
, не беспокоясь о деталях выполнения. Вот как работает Executor
. Вы submit
или execute
a Callable
или Runnable
соответственно, и нет необходимости указывать Thread.
Итак, я хотел бы знать, почему бы не использовать join()?
Тогда вот ваша причина. Поскольку вы не создаете или не манипулируете Threads в мире Executor, нет смысла использовать join
. Почти каждый join
можно заменить чем-то другим (Future.get
, CountDownLatch
, Locks
и т.д.).
Примечание. Я не говорю, что вам не нужно манипулировать потоками при использовании исполнителей. В некоторых случаях лучше создать собственный подкласс Thread, а затем использовать Executor через ThreadFactory
.
Ответ 2
Нет ничего плохого в использовании Thread.join в целом, однако вам нужно быть очень осторожным и знать, откуда поток идет из. Если это происходит из пула потоков - тогда у вас действительно есть проблемы, потому что такие потоки работают до тех пор, пока пул не будет разорван и не будет разделен между несколькими рабочими.
Ответ 3
IMO нет ничего плохого в соединении. Вам просто нужно позаботиться о том, чтобы поток, который вы ожидаете, завершался при любых обстоятельствах. Поскольку, если это не так, выполнение может быть приостановлено навсегда.
Поэтому, если вы делаете основной поток ожиданием в каком-то потоке, используя соединение, и поток не завершается, это может привести к зависанию всего приложения.
Ответ 4
A Интерфейс Fork/Join был представлен на Java 7. Подумайте об использовании его вместо Thread.join(). В общем, вы должны использовать классы из пакета java.util.concurrent. * Где это возможно, сводя к минимуму использование оригинальных методов синхронизации, таких как синхронизированные блоки, ожидание/уведомление и объединение. java.util.concurrent дает гораздо большую гибкость.