フックとデーモンスレッドを閉じる


Java仮想機会は、次の2つのイベントに応答するためにオフになります.
  • プログラムは正常に終了し、これは最後の非デーモンスレッドが終了したとき、またはexit(System.exitと同等)メソッドが呼び出されたときに発生する.または、
  • ユーザーの割り込みに応答するために、^Cなどの仮想マシンを終了する.ユーザーのログアウトやシステムのシャットダウンなどのシステムイベントが発生します.

  • フックを閉じるのは、初期化されているがまだ起動していないスレッドにすぎません.仮想マシンがシャットダウンシーケンスを有効にすると、登録されているすべてのシャットダウンフックが指定されていない順序で起動し、同時に実行されます.すべてのフックを実行した後、終了終了が有効になっている場合、仮想マシンは呼び出されていないすべての終了メソッドを実行します.最後に、仮想機会は一時停止します.シーケンスのクローズ中にデーモンスレッドが実行され続け、exitメソッドを呼び出してシーケンスのクローズを開始すると、非デーモンスレッドも実行され続けます.
    JavaアプリケーションごとにRuntimeクラスのインスタンスがあり、アプリケーションが実行されている環境に接続できるようにします.現在のランタイムは、getRuntimeの方法で取得できます.閉鎖フックはaddShutdownHook(Thread hook)によって増加した.
     
    デーモン・スレッドJavaには、「デーモン・スレッドDaemon」と「ユーザー・スレッドUser」の2つのThreadがあります.以前に見た例はすべてユーザーであり、デーモンスレッドは「バックグラウンドで汎用的なサポートを提供する」スレッドであり、プログラム本体には属していません.文字通り、デーモンスレッドは仮想マシン(virtual machine)によって内部に作成され、ユーザースレッドは独自に作成されたと理解しやすい.実際にはそうではありません.どのスレッドも「デーモン・スレッドDaemon」または「ユーザー・スレッドUser」です.彼らはほとんどの面で同じで、唯一の違いは、仮想マシンがいつ離れるかを判断することです.ユーザースレッド:Java仮想マシンは、すべての非デーモンスレッドが離れた後、自動的に離れます.≪デーモン・スレッド|デーモンThreads|emdw≫:デーモン・スレッドは、ユーザー・スレッドにサービスを提供するために使用され、他のユーザー・スレッドが実行されていない場合、サービス可能なオブジェクトがなく、継続する理由もありません.setDaemon(boolean on)メソッドは,スレッドのDaemonモードを容易に設定でき,trueはDaemonモード,falseはUserモードである.setDaemon(boolean on)メソッドは、スレッドが起動する前に呼び出さなければなりません.スレッドが実行中の場合、呼び出しに異常が発生します.isDaemonメソッドでは、スレッドがデーモンスレッドであるかどうかをテストします.特筆すべきは、1つのデーモンスレッドで他のスレッドを生成すると、これらの新しく生成されたスレッドはDaemonプロパティを設定する必要がなく、デーモンスレッドになります.ユーザースレッドも同じです.例:私たちがよく知っているJavaゴミ回収スレッドは典型的なデーモンスレッドであり、私たちのプログラムに実行中のThreadがなくなった場合、プログラムはゴミを発生せず、ゴミ回収器も何もできないので、ゴミ回収スレッドがJavaダミー上に残っているスレッドである場合、Java仮想機会は自動的に離れます.デーモンスレッドは、他のスレッドの実行に便利なスレッドです.デーモンスレッドはプログラムの終了を阻止しません.非デーモンスレッドには、従来のユーザスレッド、またはGUIイベントを処理するためのイベントスケジューリングスレッドなどが含まれる.プログラムには、デーモンスレッドと非デーモンスレッドを含めることができます.プログラムがデーモンスレッドのみの場合、プログラムは実行を終了します.スレッドをデーモンスレッドにする場合は、そのstartメソッドを呼び出す前に設定する必要があります(trueをパラメータとしてスレッドを呼び出すsetDaemonメソッドでは、そのスレッドをデーモンスレッドとして定義できます).そうしないと、IllegalThreadStateException例外が放出されます.スレッドがデーモンスレッドの場合、isDaemonメソッドは真を返します.注意:1、スレッドが開始されてから、そのスレッドをデーモンスレッドにしようとすると、IllegalThreadStateExceptionが異常になります.2、イベントスケジューリングスレッドは、デーモンスレッドではなく無限ループのスレッドです.したがって、ウィンドウベースのアプリケーションがSystemクラスのexitメソッドを呼び出すまで、イベントスケジューリングスレッドは終了しません.3、重要なタスクをデーモンスレッドに割り当てることはできません.これらのタスクは、事前に警告なしに終了し、正しく完了できない可能性があります.
    以上から:http://xpws2006.blog.163.com/blog/static/95438577200914105542761/
     
    検証手順は次のとおりです.
    package test;
    
    public class Test {
    
    	public static void main(String[] args) {
    		Thread daeman = new TestThread("daeman");
    		daeman.setDaemon(true);
    		Thread normal = new TestThread("normal");
    		daeman.setDaemon(true);
    		Thread stop = new TestThread("stop");
    		daeman.start();
    		normal.start();
    		stop.start();
    		Runtime.getRuntime().addShutdownHook(new Thread("hook"){
    			public void run(){
    				try {
    					System.out.println(getName()+" start sleep");
    					Thread.sleep(5000);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    				System.out.println(getName()+" over");
    			}
    		});
    	}
    
    }
    
    class TestThread extends Thread{
    	public TestThread(String name){
    		super(name);
    	}
    	public void run(){
    		int tick = 0;
    		while(true){
    			System.out.println(getName()+" is running "+tick);
    			try {
    				Thread.sleep(1000*1);
    				tick++;
    				if(getName().equals("normal") && tick >= 10){
    					break;
    				}
    				if(getName().equals("stop") && tick >= 5){
    					System.out.println("stop server");
    					System.exit(0);
    					break;
    				}
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    		System.out.println(getName()+" over");
    	}
    }