2012-07-13 3 views
2

자바 멀티 스레딩을 사용하려면 다음 코드를 작성해야합니다.주 스레드가 끝나기 전에 모든 스레드가 종료되었는지 어떻게 확인할 수 있습니까?

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 매우 loooong를 넣어하는 것입니다

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

풀의 원인에 관해서는 스레드 작업이 제대로 종료되지 않기 때문에 그것이 가장 가능성이 높습니다 종료 없습니다.

+0

하지만 며칠 동안 내 프로그램을 실행하고 싶지 않습니다. 스레드가 작업을 마자 마자 종료해야합니다. 적은 수의 이름으로 동일한 수의 스레드로 동일한 프로그램을 시도했을 때 (예 : 코드 에서처럼 DB에서 이름을 읽음) 예를 들어 6 개의 이름에 대해 프로그램이 완전히 시작되고 끝납니다. 그러나 2000 개의 이름을 읽을 때 마지막 스레드가 끝나지 않습니다. 그것은 영원히 남아 있습니다. 또한, System.out.println ("thread shutdown"); 절대로 인쇄하지 마십시오. –

+0

@JuryA 위의 제안은 모든 스레드가 반환되기 전에 완료 될 때까지 차단됩니다. 작은 시간 초과로 여러 번 대기하는 것이 아니라 큰 시간 초과로 한 번 대기하기 때문에 개선 된 기능입니다. –

관련 문제