1前書き

この短い記事では、** Javaで

Thread

を停止する方法について説明します。これは、__Thread.stop()メソッドが推奨されなくなったため、それほど単純ではありません。


Oracleからのこの更新

で説明されているように、]

stop()

は監視対象オブジェクトが破損する可能性があります。


2フラグを使う

スレッドを作成して起動するクラスから始めましょう。このタスクはそれだけでは終わらないので、そのスレッドを止める方法が必要です。

そのためにアトミックフラグを使用します。

public class ControlSubThread implements Runnable {

    private Thread worker;
    private final AtomicBoolean running = new AtomicBoolean(false);
    private int interval;

    public ControlSubThread(int sleepInterval) {
        interval = sleepInterval;
    }

    public void start() {
        worker = new Thread(this);
        worker.start();
    }

    public void stop() {
        running.set(false);
    }

    public void run() {
        running.set(true);
        while (running.get()) {
            try {
                Thread.sleep(interval);
            } catch (InterruptedException e){
                Thread.currentThread().interrupt();
                System.out.println(
                  "Thread was interrupted, Failed to complete operation");
            }
           //do something here
         }
    }
}


while

ループで定数

true

を評価するのではなく、

AtomicBoolean

を使用しています。これを__true/falseに設定して実行を開始または停止できます。

リンク:/java-atomic-variables[原子変数の紹介]で説明されているように、

AtomicBoolean

を使用すると、異なるスレッドから変数を設定およびチェックする際の競合を防ぐことができます。


3

Thread


を中断する


sleep()

が長い間隔に設定されている場合、または決して解放されない可能性がある


lock


を待っている場合はどうなりますか。

私たちは長期間ブロックしたり、きれいに終了したりしないというリスクに直面しています

これらの状況のた​​めに

interrupt()

を作成することができます、クラスにいくつかのメソッドと新しいフラグを追加しましょう:

public class ControlSubThread implements Runnable {

    private Thread worker;
    private AtomicBoolean running = new AtomicBoolean(false);
    private int interval;

   //...

    public void interrupt() {
        running.set(false);
        worker.interrupt();
    }

    boolean isRunning() {
        return running.get();
    }

    boolean isStopped() {
        return stopped.get();
    }

    public void run() {
        running.set(true);
        while (running.get()) {
            try {
                Thread.sleep(interval);
            } catch (InterruptedException e){
                Thread.currentThread().interrupt();
                System.out.println(
                  "Thread was interrupted, Failed to complete operation");
            }
           //do something
        }
    }
}


running

フラグをfalseに設定し、ワーカースレッドの

interrupt()

メソッドを呼び出す

interrupt()

メソッドを追加しました。

このスレッドが呼び出されたときにスレッドがスリープ状態にある場合、

sleep()

は他のブロッキング呼び出しと同様に

InterruptedException

で終了します。

これはスレッドをループに戻し、

running

がfalseのため終了します。


4結論

この簡単なチュートリアルでは、スレッドをクリーンにシャットダウンするために

interrupt()への呼び出しとオプションで組み合わされたアトミック変数の使い方を調べました。これは、廃止予定の

stop()メソッドを呼び出してロックを永遠に行ってメモリが破損する危険性があることよりも確実に望ましい方法です。

いつものように、完全なソースコードはhttps://github.com/eugenp/tutorials/tree/master/core-java-concurrency[over on GitHub]から入手できます。