2012-01-09 3 views
1

내가 다음 함수에 몇 통화를 할 가정 :VM이 Control-C에 의해 종료되면 타이머 시작 스레드가 완료되도록 할 수 있습니까?

public void StartTimedRuns(){ 
    Timer timer = new Timer(); 
    timer.scheduleAtFixedRate(new TimerTask(){ 
     public void run(){ 
      //do something that takes less than a minute 
     } 
    }, 0, 60*1000); 
} 

나의 이해는 스레드의 무리가이 시점에서 동시에 실행된다는 것입니다. 즉, 각 타이머 인스턴스는 1 분 간격으로 수명이 짧은 스레드를 생성합니다. 여기 지침에 따라 가정하자

나는 종료 후크를 설치 (I 제어-C를 누르면 실행) :

Catching Ctrl+C in Java

셧다운 후크 모든 타이머를 취소합니다. (타이머를 클래스 수준 컬렉션에 저장한다고 가정하십시오.)

VM이 종료되기 전에 모든 활성 스레드가 완료 될 것이라고 보장 할 수 있습니까?

관련하여 종료 훅은 스레드가 모두 종료 될 때만 호출됩니까?

답변

5

메인 스레드가 완료되거나 Ctrl + C를 통한 키보드 인터럽트가 발생할 때 종료 훅이 호출됩니다.

활성 스레드가 완료 될 때까지 실행되도록하려면 종료 훅에서 명시 적으로 join()이어야합니다. TimerTask들에 의해 사용되는 스레드가 사용자에게 직접 노출되지 않기 때문에이 약간 까다 롭습니다,하지만 당신은 수업 시간에 이런 식으로 뭔가를 넣을 수 있습니다 :의 맨 위에이 같은

private static List<Thread> timerThreads = new LinkedList<Thread>(); 

그리고 뭔가 TimerTask.run() 방법 : 종료 훅이 같은

timerThreads.add(Thread.currentThread()); 

그리고 뭔가 :

try { 
    for (Thread t : timerThreads) { 
     t.join(); 
    } 
} catch (InterruptedException e) { 
    // handle it somehow 
} 

이 보장하는 모든 활성 스레드가 완료 될 때까지 실행됩니다. 그러나 반드시 좋은 생각은 아닙니다. the API documentation을 인용 :

종료 후크는 가상 시스템의 라이프 사이클에 민감한 시간에 실행 때문에 수비에 코딩해야합니다. 특히, 에서 thread-safe로 작성하고 가능한 교착 상태를 피하려면 을 사용해야합니다. [...] 셧다운 훅은 작업을 빨리 완료해야합니다. 프로그램에서 exit을 호출하면 이라는 가상 컴퓨터가 즉시 종료되고 종료됩니다. 사용자 로그 오프 또는 시스템 종료로 인해 가상 머신이 종료되면 기본 운영 체제는 종료하고 종료 할 에 고정 된 시간 만 허용 할 수 있습니다. 따라서 어떤 사용자 상호 작용이나 종료 훅에서 장기 실행 계산을 수행하려고 시도하는 것은 바람직하지 않습니다.