どのようにスレッドを優雅に中止するには?

この記事では、スレッドアボート正常に学習する方法を学習するには?病気や死のJavaスレッドの研究で、私はその後、我々は今のスレッドアボート学び、我々はいくつかの実行中のスレッドの理解だけでなく、スレッドの状態を持っていると信じて:

ストップ - アボート間違ったスレッド

まずは、スレッドを終了するために間違った方法を説明しましょう- stopスレッドアボート、および明確な情報モニタのロックが、スレッド安全性の問題につながる可能性があり、JDKもDestoryは同様のアプローチを使用することは推奨されません、JDKは、この方法によるマテリアライズドことはありませんここで提示されていないインチ

理由を説明するためのプログラムが続くstopリードは安全性の問題を通すために?

最初のスレッドのクラスを定義しますStopThread

public class StopThread extends Thread {
    private int i = 0;
    private int j = 0;

    @Override
    public void run() {
        synchronized (this) {
            // 增加同步锁,确保线程安全
            ++i;
            try {
                // 休眠10秒,模拟耗时操作
                Thread.sleep(10000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            ++j;
        }
    }

    /**
     * 打印 i 和 j
     */
    public void print() {
        System.out.println("i=" + i + " j=" + j);
    }
}

行うにはこのスレッドは同期コードブロックにあるij、これらの二つの変数のインクリメント演算子が、睡眠の10秒の場合、プロセスであれば、この実行手順では、stopスレッドがメソッドを中断され、その後、意志鉛ijメインスレッドがの作成に影響するため、データが誤っている、それは、プログラミング上のスレッド安全性の問題を言うことができるStopThreadのスレッドが不正確データを、理想的な正しい出力は、我々は追加するのでどちらかのすべてのアドオンは、成功するか失敗する必要があります目的はアトミックロックの動作を保証する場合や、運転中に他のスレッドからの干渉なしに、これらの2つの変数をしたいです。

以下の書き込みStopThreadDemoに使用するクラスをstop、エラーのデモンストレーションする方法を:

public class StopThreadDemo {
    public static void main(String[] args) throws InterruptedException {
        StopThread thread = new StopThread();
        thread.start();
        // 休眠 1 秒,确保 i 变量自增成功
        Thread.sleep(1000);
        // 暂停线程
        thread.stop(); // 错误的终止
        while (thread.isAlive()) {
            // 确保线程已经终止
        } // 输出结果
        thread.print();
    }
}

ではStopThreadDemo、クラス、作成して開始しStopThreadた実行変数の下で、スレッド、iおよびjインクリメント演算子を、しかし、インクリメント操作はそうすることのブロックsynchronizedキーワード小包2つの変数のインクリメント演算子を作ることである同期され達成アトミックのスレッドの安全性を確保するために、他のスレッドからの干渉を受けることなく、。

しかし、によって睡眠に10秒のスレッド内でstopオフアボートスレッドの方法、出力結果を見つけるだろうi=1 j=0、私のコード増分のすなわち最初の半分が実装されますが、増分の半分はJを失敗した後、データが表示されますスレッドします矛盾、それによって標的の同期コード・ブロックを確保するためには、セキュリティスレッドを損なう、原子に達していません。

割り込み - 中止正しいスレッド

間違った方法を停止する導入では、のが正しいスレッドアボートを学びましょう- interrupt

ターゲットスレッドが呼び出した場合は障害物の方法を、そしてそれが有効になり、スレッドの割り込みステータスがクリアされます、スロー例外を。Object classwait() 、wait(long) 或 wait(long,int) 方法、join()、join(long,int) 或 sleep(long,int)interruptInterruptedException

ターゲットスレッドがチャネルでのIOまたはNIOによってブロックされている場合は、同じIO操作が中断復帰特別な外れ値、サスペンションスレッドの目的となります。

上記の条件が満たされない場合、割り込みステータスは、このスレッドを設定します。

次はStopThreadDemostopに変更interrupt操作した結果が何であるかを見て:

java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.wupx.thread.StopThread.run(StopThread.java:18)
i=1 j=1

インクリメント2つの変数が、実行のデータの一貫性を確保するために適切に行うことができます見つけることができinterrupt、割り込みスレッドが直接、中断を余儀なくされていないが、例外は、開発者が異常な領収書の実行ロジックを制御することができ、弊社に通知スローされます、プログラム全体がJDKの現在のバージョンが推奨され、スレッドセーフな状態であるようにinterrupt方法。

加えて、interrupt外部の正しい方法、あなたはまた、フラグの形でスレッドを中止することができます。

旗 - 中止正しいスレッド

コード・プログラム・ロジックはループサービスで実行される場合、このように次のコードとして、実行スレッドコードプログラムにフラグを増加させるwhileことにより、このプログラムを実行するループflag、プログラムの制御を継続するか否か雄ねじ場合flag変更falseサスペンションの効果を達成するように変化は、この変数の形で、他のスレッド、制御のスレッドに通知し、このデータを受信する作成サブスレッドコード。

public class FlagThreadDemo {
    public volatile static boolean flag = true;

    public static void main(String[] args) throws InterruptedException {
        new Thread(() -> {
            try {
                while (flag) { // 判断是否运行
                    System.out.println("运行中");
                    Thread.sleep(1000L);
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        // 3 秒之后,将状态标志改为 false,代表不继续运行
        Thread.sleep(3000L);
        flag = false;
        System.out.println("程序运行结束");
    }
}

次のようにコードを実行すると、結果は以下のとおりです。

运行中
运行中
运行中
程序运行结束

プログラムは、条件フラグはこの方法を行うために使用することができているならば、あなたが行うことができ、実行するビジネスロジックのスレッドに限られ、この方法ではなく、正しいスレッドを一時停止する方法。

概要

:この記事では、スレッドの終了には3つの方法を説明しstopinterrupt同様にフラグとして、我々はそれを得た、メッセージを議論する歓迎します。

公共号にソースコード[ Wupeiスアン [における返信] 並行 ]取得。

おすすめ

転載: www.cnblogs.com/wupeixuan/p/12578851.html