割り込み割り込みスレッドを停止

つまり、状態の6の合計スレッド:

新しい、Runnableを、ブロックされ、待つ、時限Watingは、終端

whileループ時にRunnableのrun次の方法を分析する場合、外部のスレッドで循環させながら、実行スレッドを停止する方法。

コードの一部を見てください

    public static void main(String[] args) throws Exception{
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                int num = 0;
                while (num < Integer.MAX_VALUE){
                    System.out.println(Thread.currentThread().getName() + "正在执行");
                }
            }
        });
        t0.start();

        TimeUnit.MILLISECONDS.sleep(100);

        // 执行t0.interrupt(),但是t0仍会继续运行
        t0.interrupt();
    }

私たちは、()は、スレッドが実行を停止することはできませんでした割り込み見ることができます。

ロールinterrput()は、スレッドの割り込みステータスがt0.interruptの実装後にそれを言っていない、trueに設定されている()、T0スレッド終端(終了状態)に入ります。

2例では、スレッドが終了状態になります。

    1、実行するメソッドの終了を実行します。

    2、runメソッドは例外をスローします。

フラグ割り込み割り込みスレッドがtrueに設定されているので、ループが偽である一方で、それが終了し、入力する割り込みステータスの割り込み状態t0の判断にwhileループの条件を決定するループは、runメソッドの実行の終わりには、スレッドがなったときに、真の間の状態のため終了しました。

Thread.currentThread()。isInterruptedを()によってスレッドの割り込み状態を得ることができます

    public static void main(String[] args) throws Exception{
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                // 当前线程的中断状态为true则退出while循环
                while (!Thread.currentThread().isInterrupted()){
                    System.out.println(Thread.currentThread().getName() + "正在执行");
                }
            }
        });
        t0.start();

        TimeUnit.MILLISECONDS.sleep(100);

        // 执行t0.interrupt(),t0的中断状态变为true
        t0.interrupt();
    }

上記のコードを実行し、スレッドが実際に停止しました。

しかし、スレッドが例外:InterruptedExceptionをスローT0際には注意するスレッドの割り込みステータス・必要性を得るためにisInterruptedを()を使用して、JVMは、状態が偽のT0に設定されている中断されます。

次のコードを見てください

    public static void main(String[] args) throws Exception{
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                while (!Thread.currentThread().isInterrupted()){
                    try {
                        System.out.println(Thread.currentThread().getName() + "正在执行");

                        // 在线程中加入sleep()这种可以响应中断的代码,并在while循环中把异常捕获
                        TimeUnit.MILLISECONDS.sleep(1);
                    }catch (InterruptedException e){
                        // 发生InterruptedException之后,线程的中断状态会被变成false
                        e.printStackTrace();
                    }
                }
            }
        });
        t0.start();

        TimeUnit.MILLISECONDS.sleep(100);

        t0.interrupt();
    }

上記のコードは、その後InterruptedExceptionあるが発生するため、ステータス割り込みスレッドは偽となり、永遠に実行されます。正しい方法は本あってはならない:キャプチャInterruptedExceptionある後、もはやrunメソッドでwhileループを実行します。

    public static void main(String[] args) throws Exception{
        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (!Thread.currentThread().isInterrupted()){
                        System.out.println(Thread.currentThread().getName() + "正在执行");
                        // 在线程中加入sleep()这种可以响应中断的代码
                        TimeUnit.MILLISECONDS.sleep(1);
                    }
                // 将捕获异常的代码放到while循环之外,捕获异常之后不再有循环代码
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t0.start();

        TimeUnit.MILLISECONDS.sleep(100);

        t0.interrupt();
    }

上記のコードはスレッドT0を終了することを、実行されないであろう。

私たちがキャッチした場合InterruptedExceptionがJVMのスレッドの割り込みステータスが自動的にrunメソッドにfalseに設定されていると考えなければなりません。

もう一つの方法は、一方で停止するように変更揮発性のブール変数を使用することであるが、このアプローチはまた、すぐにスレッドを停止しない、バグがあります。

    // 停止生产标识
    public static volatile boolean stopProduce = false;

    public static void main(String[] args) throws Exception{
        // 资源队列,用于公共存储资源
        LinkedBlockingQueue lbq = new LinkedBlockingQueue(3);

        Thread t0 = new Thread(new Runnable() {
            @Override
            public void run() {
                int i = 0;
                try {
                    while (i<Integer.MAX_VALUE && !stopProduce){
                        System.out.println("生产 "+i);
                        /**
                         * 当LinkedBlockingQueue队列满了,put方法会将线程设置为WAIT状态
                         * 若没有消费者消费LinkedBlockingQueue中的资源,线程会一直在这里等待,没法运行while判断
                         */
                        lbq.put(i);
                        i++;
                    }
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t0.start();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    while (new Random().nextInt(100)>5){
                        // 消费资源
                        System.out.println("消费 "+lbq.take());
                    }
                }catch (InterruptedException e){
                    e.printStackTrace();
                }
            }
        });
        t1.start();

        TimeUnit.MILLISECONDS.sleep(10);

        // 设置停止生产标识为true,但是t0立刻没有停止,还处于WAIT状态
        stopProduce =true;

        // 消费一个LinkedBlockingQueue的资源后,t0从WAIT状态变为RUNNABLE,执行while判断后退出循环,线程结束
        //lbq.take();
    }

 

 

 

 

公開された51元の記事 ウォン称賛14 ビュー40000 +

おすすめ

転載: blog.csdn.net/u010606397/article/details/103891954