JAVA関門問題-スレッド実行時にKillを落とすことができるかどうか

3448 ワード

転入(削除):http://blog.163.com/xh_ding/blog/static/193903289201341685931689
Javaのスレッドをどのように停止するかは、マルチスレッドプログラムを開発する上でよく発生する問題です.多くの人が私に聞いたことがあるので、今日はjavaで実行中のスレッドをどのように安全に終了するかをもっと多くの人に知ってもらいたいとまとめました.
Javaのマルチスレッドプログラミングでは、java.lang.Threadタイプには、いくつかの列のメソッドstart()、stop()、stop(Throwable)and suspend()、destroy()and resume()が含まれています.これらの方法により,スレッドを容易に操作できるが,これらの方法ではstart()法のみが保持されている.
JDKヘルプドキュメントおよびSun社の記事『Why are Thread.stop,Thread.suspend and Thread.resume Deprescated?』では、これらの方法を捨てる理由を説明しています.
では、スレッドをどのように停止すればいいのでしょうか.ここでは2つの方法を紹介します.
  • 共有変数を使用する方法この方法では、共有変数が導入されるのは、同じタスクを実行する複数のスレッドによって、割り込みの有無の信号として使用され、割り込みスレッドの実行を通知することができるからである.
  • public class ThreadFlag extends Thread 
    
    { 
    
        public volatile boolean exit = false; 
    
        public void run() 
    
        { 
    
            while (!exit); 
    
        } 
    
        public static void main(String[] args) throws Exception 
    
        { 
    
            ThreadFlag thread = new ThreadFlag(); 
    
            thread.start(); 
    
            sleep(3000); //      3  
    
            thread.exit = true;  //     thread 
    
            thread.join(); 
    
            System.out.println("    !"); 
    
        } 
    
    } 
    
    上記のコードでは、exitがtrueの場合、whileループが終了し、exitのデフォルト値がfalseになる終了フラグexitが定義されています.exitを定義するときにJavaキーワードvolatileが使用されます.このキーワードの目的はexitを同期させることです.つまり、同じ時点でexitの値を変更できるのは1つのスレッドだけです.
    『Why Are Thread.stop,Thread.suspend,Thread.resume and Runtime.runFinalizersOnExit Deprescated?』では、スレッドを停止するには、次の方法をお勧めします.
      private volatile Thread blinker; 
    
        public void stop() { 
    
            blinker = null; 
    
        } 
    
        public void run() { 
    
            Thread thisThread = Thread.currentThread(); 
    
            while (blinker == thisThread) { 
    
                try { 
    
                    thisThread.sleep(interval); 
    
                } catch (InterruptedException e){ 
    
                } 
    
                repaint(); 
    
            } 
    
        }
    
    2.interruptメソッドを使用してスレッドを終了する
    あるイベントの発生を待つためにスレッドがブロックされた場合、スレッドをどのように停止しますか?このようなことは、キーボード入力を待つ必要があるためにスレッドがブロックされたり、Thread.join()メソッドが呼び出されたり、Thread.sleep()メソッドが呼び出されたり、ネットワークでServer Socket.accept()メソッドが呼び出されたり、DatagramSocket.receive()メソッドが呼び出されたりすると、スレッドがブロックされてスレッドが実行不可能になる可能性があります.メインプログラムでスレッドの共有変数をtrueに設定しても、ループフラグをチェックすることはできません.もちろん、すぐに中断することはできません.ここではstop()メソッドを使用するのではなく、実行中のスレッドを中断することはありませんが、ブロックされたスレッドに割り込み異常を投げ出し、スレッドを早期にブロック状態を終了させ、ブロックコードを終了させることができるため、Threadが提供するinterrupt()メソッドを使用することを提案します.
    class MyThread extends Thread {
    
    volatile boolean stop = false;
    
    public void run() {
    
    while (!stop) {
    
    System.out.println(getName() + " is running");
    
    try {
    
    sleep(1000);
    
    } catch (InterruptedException e) {
    
    System.out.println("week up from blcok...");
    
    stop = true; //                  
    
    }
    
    }
    
    System.out.println(getName() + " is exiting...");
    
    }
    
    }
    
    class InterruptThreadDemo3 {
    
    public static void main(String[] args) throws InterruptedException {
    
    MyThread m1 = new MyThread();
    
    System.out.println("Starting thread...");
    
    m1.start();
    
    Thread.sleep(3000);
    
    System.out.println("Interrupt thread...: " + m1.getName());
    
    m1.stop = true; //        true
    
    m1.interrupt(); //          
    
    Thread.sleep(3000); //      3       m1     
    
    System.out.println("Stopping application...");
    
    }
    
    }
    
    注意:Threadクラスでは、スレッドがinterruptメソッドによって終了したかどうかを判断する2つの方法があります.1つは静的メソッドinterrupted()であり、1つは非静的メソッドisInterrupted()であり、この2つのメソッドの違いはinterruptedが現在の線が中断されているかどうかを判断し、isInterruptedが他のスレッドが中断されているかどうかを判断するために使用できることである.