2012-07-13 2 views
2

У меня есть следующий фрагмент кода для использования многопоточности java.Как я могу убедиться, что все потоки закончились до окончания основного потока?

ExecutorService threadExecutor = Executors.newFixedThreadPool(10); 

    while(resultSet.next()) 
     { 
      name=resultSet.getString("hName"); 
      MyRunnable worker = new Myrunnable(name); 
      threadExecutor.execute(worker); 
      Counter++; 
    } 


threadExecutor.shutdown(); 
System.out.println("thread shutdown"); 

// Wait until all threads are finish 
while (! threadExecutor.isTerminated()) { 

} 

System.out.println("Finished all threads"); 

}// end try 
    catch (Exception e) { 
     e.printStackTrace(); 
    } 

    System.out.println("END MAIN"); 

    DBConnection.con.close();   

И функция запуска следующим образом:

//The constructor 
MyRunnable (String name) { 
     this.name=name; 
    } 

public void run() 
{ 
     myclass Obj=new myclass(); 
     try { 
      Obj.myFunction(name); 
     } catch (Exception e) { 

      System.out.println("Got an Exception: "+e.getMessage()); 
     } 
     System.out.println(" thread exiting."); 
} 

В предыдущих сообщениях, кто-то предложили следующий код, чтобы ждать резьбы до конца.

while (! threadExecutor.isTerminated()) { 
    try { 
     threadExecutor.awaitTermination(1, TimeUnit.SECOND); 
    } 
    catch (InterruptedException e) { 
     // you have to determine if someone can interrupt your wait 
     // for the full termination of the executor, but most likely, 
     // you'll do nothing here and swallow the exception, or rethrow 
     // it in a RuntimeException 
    } 
} 

Теперь я столкнулся с проблемой в обоих случаях. Если я использовал первый метод, моя программа запускается, но в конце он вводит бесконечный цикл, которому предшествуют все потоки, выходящие. Распечатка END MAIN никогда не появляется. Если я использовал второй метод, у меня появилась следующая ошибка с начала запуска программы, а также распечатка END MAIN никогда не появляется:

Получено исключение: после закрытия соединения никаких операций не разрешено. нить выходить.

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

+0

Цикл while может голодать планировщик, попробуйте поместить Thread.sleep (250) или Theead.yield в него – MadProgrammer

+0

где поставить Thread.sleep (250) или Theead.yield? Не могли бы вы прояснить больше, так как я новичок в многопоточности. –

+0

Извините, в цикле while, который вы используете, чтобы подождать, пока закончится другой поток. – MadProgrammer

ответ

3

Прежде всего, почему все заняты прядением? Наиболее CPU-эффективным методом является просто поставить очень awaitTermination займет слишком много:

threadExecutor.shutdown(); 
threadExecutor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS); 

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

+0

Но я не хочу, чтобы моя программа работала несколько дней. Мне нужно, чтобы он закончился, как только потоки закончат работу. Когда я пробовал ту же программу с тем же количеством потоков для меньшего количества имен (я читал имена из БД, как показано на коде), например, для 6 имен программа запускается и заканчивается отлично. Но когда я читаю 2000 имен, последние потоки не заканчиваются. Он остается навсегда. Кроме того, System.out.println («shutdown»); никогда не распечатывайте. –

+0

@JuryA Предложение, указанное выше, будет заблокировано до тех пор, пока все потоки не будут завершены до их возвращения. Это улучшение, потому что вы ждете один раз с большим таймаутом, а не ожидаете много раз с небольшим таймаутом. –

Смежные вопросы