同時プログラミングスレッド割り込みフラグとスレッド割り込みフラグ

11154 ワード

転送先:http://blog.csdn.net/qq_24692041/article/details/78455131
スレッド中断、interruptメソッド
 コードと出力結果を先に見て
 サブスレッドコード:
package com.example;

/**
 * Created by PICO-USER on 2017/11/6.
 */

public class ThreadA extends Thread {
 
    @Override
    public void run() {
        super.run();
        try{
            System.out.println("in ThreadA - about to sleep for 20 seconds :"+isInterrupted());
            Thread.sleep(20000);
            System.out.println("in ThreadA - wake up");
        }catch(InterruptedException e){
            System.out.println("in ThreadA - interrupted while sleeping");
            System.out.println("in ThreadA - interrupt status of threadA :"+isInterrupted());
            //run()    ,
            //    return,         ,           
          //  return;
        }
        System.out.println("in ThreadA - leaving normally");
    }
}

メインスレッドコード:
package com.example;

public class MyClass {

    public static void main(String[] args0) throws InterruptedException {

        ThreadA threadA = new ThreadA();
        threadA.start();

        //     2        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("in main() - interrupting other thread");
        //    t
        threadA.interrupt();
        System.out.println("in main() - interrupt status of threadA :"+threadA.isInterrupted());
        System.out.println("in main() - leaving");
    }
}
出力結果:
并发编程线程中断和线程中断标志_第1张图片
コードと結果分析:
メインプログラムでスレッドAが起動すると、スレッドAのrunメソッドが実行され、「in run()-about to sleep for 20 seconds」が印刷された後、Aはスリープ状態に入り、20秒スリープする.このときメインスレッドは同時実行され,メインスレッドは2秒休止し,2秒後にメインスレッドはスリープ終了し,interruptメソッドを呼び出してAスレッドを中断し,メインスレッドmainメソッドは実行済みであるため,メインスレッドは消滅する.このときAスレッドはまだスリープ状態にあるはずだったが,interruptメソッドが呼び出されたため,直接Aスレッドにスリープ状態を終了させて割り込み異常を投げ出し,try,catchの後のコードを実行し続け,runメソッドが完了すると消滅する.ここで、catchブロックでreturnを使用すると、runメソッドの実行が終了すると、Aスレッドが直接消滅するため、後続のコードは実行されません.
ポイント:上記のコードからinterruptメソッドの呼び出しは、ターゲットスレッドに割り込みフラグtrueが設定されているだけで、スレッドが割り込まれていることを示し、スレッドを直接終了することはありません.注意isInterruptメソッドが印刷された結果、Aスレッドがrunメソッドを実行し始めたときに印刷されたのはfalseで、それからAスレッドを中断した瞬間、私たちはメインスレッドでAスレッドを印刷した中断状態がtrueで、最後にAスレッドのcatchブロックに印刷されたのはfalseで、interruptメソッドの呼び出しを説明するときに確かに中断フラグが設定されています.スレッドの実行は直接終了しません.
スレッドがsleep,wait,joinメソッドを呼び出すなどのブロックに遭遇すると、割り込み異常が放出され、割り込みフラグがリセットされます.したがって、上記のcatchメソッドのisInterruptメソッドはfalseを返します.
最後に、実は私たちがメインスレッドでAスレッド割り込みフラグを印刷したときに偶然の疑いがありましたが、印刷の位置だけですね.interruptが割り込みフラグを設定した結論は間違いありません.メインスレッドでAの割り込みフラグを印刷すると、Aの異常が投げ出され、割り込みフラグがリセットされる可能性があるので、その結果falseになります.
メソッド判定スレッド割込み
スレッド割り込み判定方法は2つあり、1つはinterrupted()方法であり、この方法は静的方法であり、この方法は現在のスレッドを割り込み、この方法は割り込みフラグをリセットし、もう1つの方法は、上述したisInterrupted()方法であり、この方法は非静的方法であり、オブジェクトに作用し、ターゲットスレッドの割り込みフラグを返す.それ自体は割り込みフラグをリセットするわけではありません.sleep,wait,joinメソッドを呼び出して割り込みフラグをリセットするなど、スレッドブロックが必要です.次の2つのサンプルコードを見てみましょう.
package com.example;

/**
 * Created by PICO-USER on 2017/11/6.
 */

public class ThreadB extends Thread {

    @Override
    public void run() {
        super.run();
        System.out.print("ThreadB isInterrupted :"+isInterrupted()+"
"); System.out.print("ThreadB interrupted :"+ThreadB.interrupted()+"
"); interrupt(); System.out.print("ThreadB isInterrupted :"+isInterrupted()+"
"); System.out.print("ThreadB isInterrupted :"+isInterrupted()+"
"); System.out.print("ThreadB interrupted :"+ThreadB.interrupted()+"
"); System.out.print("ThreadB interrupted :"+ThreadB.interrupted()+"
"); } }
package com.example;

public class MyClass {

    public static void main(String[] args0) throws InterruptedException {

        ThreadB threadB = new ThreadB();
        threadB.start();
        System.out.print("main :" + Thread.currentThread().isInterrupted() + "
"); } }
実行結果:
并发编程线程中断和线程中断标志_第2张图片
interruptメソッドを呼び出した後に連続して印刷された2回のisInterruptedの戻り値はtrueであることはよくわかりますが、1回目のinterruptedメソッドの戻り値はtrueですが、2回目の呼び出しではfalseにリセットされました.