출처 : http://forum.falinux.com/zbxe/index.php?document_srl=807633&mid=lecture_tip

참고 : http://kimseunghyun76.tistory.com/381

Java API : http://docs.oracle.com/javase/8/docs/api/java/lang/Runtime.html#addShutdownHook-java.lang.Thread-


Java에서 어플리케이션을 종료 될때 뭔가를 작업 하고 싶을 경우에 addShutdownHook이란 걸 사용 할 수 있습니다.


addShutdownHook은 VM에서 사라지기 전에 마지막 유언을 할 수 있게 해줍니다.^^;


 Ctrl+C, 또는 kill명령으로 강제 종료가 될때도 실행이 됩니다. 위에서 말했듯 마지막 유언을 남기기 위해....


그럼 샘플 소스입니다.


[샘플 소스]

public class ShutdownHookDemo {

	static class ByeMessage extends Thread {

		public void run() {
			System.out.println("프로그램이 종료 되었습니다.!!!!");
		}
	}

	public static void main(String[] args) {

		// 자바가 종료 될때 실행 시킬 쓰레드를 등록 시킴.
        Runtime.getRuntime().addShutdownHook(new ByeMessage());
        
        try {
	        // 프로그램 시작 메세지
	        System.out.println("프로그램 시작!!!!");
	
	        // 3초간 대기 함.
	        System.out.println("대기 3초!!!");
	        Thread.sleep(3000);
	
	        // 프로그램 종료
	        System.out.println("프로그램 종료!!!");
	        
        } catch(Exception e) {
        	e.printStackTrace();
        }
	}
}


- 익명 (
anonymous) class 사용

public class ShutdownHookDemo {

	public static void main(String[] args) {

		// 자바가 종료 될때 실행 시킬 쓰레드를 등록 시킴.
        Runtime.getRuntime().addShutdownHook(new Thread() {
            public void run() {
                System.out.println("프로그램이 종료 되었습니다.!!!!");
            }
        });
        
        try {
	        // 프로그램 시작 메세지
	        System.out.println("프로그램 시작!!!!");
	
	        // 3초간 대기 함.
	        System.out.println("대기 3초!!!");
	        Thread.sleep(3000);
	
	        // 프로그램 종료
	        System.out.println("프로그램 종료!!!");
	        
        } catch(Exception e) {
        	e.printStackTrace();
        }
	}
}




[실행]

shutdown_1.PNG 



addShutdownHook에는 쓰레드가 등록 됩니다.


샘플에는 대기를 3초로 하고 이클립스에서 실행 시켜서 정상적으로 종료 하도록 하였지만,


 커멘드창에서 프로그램을 실행 시킨후, 3초가 되기전에 Ctrl+C를 눌러 종료 시키면 


"프로그램이 종료 되었습니다.!!!!"라는 메세지가 뜨고 "프로그램 종료!!!!"라는 메세지는 뜨지 않습니다.




* addShutdownHook 사용 시 주의점

- Shutdown hooks의 개수 : 제한 없다.

- Shutdown hook을 붙여야 하는 시점은 언제든지 붙여도 된다. 
  단순한 이야기 이지만, 셧다운 되기 전에 어떤 인스턴스든지 붙여놔야 겠지.

- 같은 hook을 다시 붙이는 것은 할수 없다."Hook previously rfegisted"라는 IllegalArgumentException이 발생한답니다.

- De-register a Hook : Runtime.removeShutdownHook 메소드를 호출하는 것 만으로, 훅을 제거 할 수 있다. 

  하지만 익명 내부 클래스를 사용해서 셧다운을 대부분 등록하는데, 이 것을 사용할수 있는 어떤 참조도 가질수 없기 때문에, 우리는 익명 내부 클래스를 우리가 제거할지 모르는 훅들에 대해서는 사용하면 안된다. 

removeShutdownHook 메소드에 이 참조를 전달 해야하기 때문이랍니다.

- 동시성을 유지하는 것을 지켜요 : 앞서 말한대로.

- Shutdown Hook의 Reliability(신뢰도) : JVM은 최선을 다해 실행하겠지만, 모두 다 실행된다고 보장 할 수 없다고 한다. 

- Hook들에 의한 시간 소비를 유의해라 : 셧다운 할 때 시간 소비 하지 않는것이 중요하다. 



+ Recent posts