2015-10-11 3 views
1

Я решаю многопоточную проблему на 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()) ; 
} 

, но это не кажется слишком изящным.

+0

Вам следует рассмотреть возможность использования [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

ответ

0

Ваш отредактированный код внизу, это будет цикл forever, прежде чем он повторит операцию for() дважды.

+0

Что вы имеете в виду? Он будет работать, несмотря на то, что существуют большие «потоки». Он получает поток в 'i', прерывает его, а затем оживляет, пока поток не прерывается. – Zach

+1

Почему бы не поспать? Это экономически выгодно для ресурсов. –

+0

Это сработало отлично! спасибо – Zach