Я решаю многопоточную проблему на Java и решаю основную проблему, но мой результат не то, что я ожидал.Присоединиться() к нескольким потокам и обработать утечку вывода
У меня есть основной поток, который закручивает новые потоки, каждый из которых выполняет свои задачи. Это выглядит следующим образом (псевдокод):
initializeThreads(); // Creates the new threads
startThreads(); // Starts the new threads
sleep(duration); // Lets the threads run for `duration` time
shutdownThreads(); // interrupt the threads
printOutput(); // output the results to the console
// definition of shutdownThreads() is at the end of my question
Моя проблема возникает при попытке join()
на каждом потоке в моем списке потоков. Время от времени моя программа попадает в бесконечный цикл, потому что я предполагаю, что interrupt()
Я звоню в свой список потоков не так быстро, как по сравнению с join()
, и не все потоки прерываются.
Другая проблема возникает, когда программа делает правильно отключает потоки и печатает выходные данные о завершении. Во время работы программы каждый поток имеет сообщения, которые он регистрирует на консоли, и после того, как я прерываю потоки и отображаю окончательное сообщение о программе, некоторые из этих сообщений, связанных с конкретным потоком, просачиваются в консоль.
Например, один из моих потоков выдает "Thread-1 waiting for lock on object..."
во время его запуска, и основная программа, наконец, просыпается вверх, завершает поток и выдает "Program finished"
. Иногда сообщение, связанное с потоком, отображает после сообщения о завершении программы.
Если кто-нибудь может помочь мне разобраться, как остановить это, пожалуйста, дайте мне знать!
shutdownThreads()
private void shutdownThreads() {
Thread t;
for (int i = 0; i < threads.size(); i++) {
t = threads.get(i);
t.interrupt();
}
for (int i = 0; i < threads.size(); i++) {
t = threads.get(i);
try {
t.join();
} catch (InterruptedException e) {
System.out.println("Interrupted while waiting on thread to exit");
}
}
}
EDIT: Одна вещь, я думал, что делать это переписывание shutdownThreads()
сделать это:
for (int i = 0; i < threads.size(); i++) {
Thread t = threads.get(i);
t.interrupt();
while (!t.isInterrupted()) ;
}
, но это не кажется слишком изящным.
Вам следует рассмотреть возможность использования [ExecutorService] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html). Вместо создания потоков вы просто отправляете Callables в ExecutorService [invokeAll] (https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/ExecutorService.html#invokeAll-java.util .Collection-long-java.util.concurrent.TimeUnit-). – VGR