Как выполнить фрагмент кода только после завершения всех потоков
-
18-09-2019 - |
Вопрос
У меня есть код регистрации, который все-таки нужно выполнить. Threads
s выполняются.
Thread t1 = new MyThread();
Thread t2 = new MyThread();
t1.run();
t2.run();
doLogging();
Есть ли способ выполнить doLogging()
только после того, как оба потока завершат свою обработку.Теперь, когда doLogging()
вызывается, как только запускаются t1 и t2.
Решение
Только join()
все темы перед вашими doLogging()
вызов:
t1.join();
t2.join();
// the following line will be executed when both threads are done
doLogging();
Обратите внимание, что порядок join()
вызовы не имеют значения, если вы хотите дождаться всех своих потоков.
Другие советы
В дополнение к решению join() в библиотеке java.util.concurrent есть еще что-то под названием CountDownLatch.Это позволяет вам инициализировать его определенным числом, а затем ждать, пока оно не будет выполнено указанное количество раз.
Простой пример:
CountDownLatch latch = new CountDownLatch(NUMBER_OF_THREADS);
for(int i=0; i<NUMBER_OF_THREADS;i++)
new Thread(myCode).start();
latch.await();
Однако, чтобы это работало, защелка должна быть явно задействована рабочими потоками:
latch.countDown()
Если вы запускаете код из основного потока, имейте в виду, что это приведет к зависанию пользовательского интерфейса до завершения обоих потоков.Это может быть не желаемый эффект.
Вместо этого вы могли бы рассмотреть конструкцию, в которой каждый поток синхронизируется по вашему Logger
объект и выполнять вызовы к нему внутри этой конструкции.Поскольку я не знаю, чего конкретно вы пытаетесь достичь, другим решением является то, что Иоахим предложил, размещая этот код только внутри потока.