1

以前は実行できなかったスレッドがありますが、このサイトのメンバーのおかげで解決されました。その質問はここにあります。

スレッドを停止するには、スレッド クラスでブール値を作成し、それをfalseに設定します。trueに設定すると、スレッドが停止するはずです。スレッドを印刷してスレッドを停止しているときも確認しますが、trueと印刷されますが(そうあるべきです)、スレッドは実行され続けます。

私のスレッド ( CheckFiles.java ) クラスは次のようになります。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

class CheckFiles extends Thread {

    static boolean stop = false;

    public void run() {
        while (!stop) {
            System.out.println("Thread " + stop);
            try {

                String line;

                BufferedReader b = new BufferedReader(new FileReader(UserInterface.location));

                while((line = b.readLine()) != null) {

                    Ststem.out.println(line);
                }

            } catch (IOException e) { System.out.println(e); }

        }
    }

}

スレッドを停止するには、ボタンがあり、そのコードは次のようになります。

 stopChecking.addMouseListener(new MouseAdapter() {
        @Override
        public void mousePressed(MouseEvent e) {

            CheckFiles.stop = true;
            System.out.println(CheckFiles.stop); //Prints true when pressed

        }
    });

スレッドが停止しないのはなぜですか、またはそれを行うためのより良い方法はありますか?

編集:スレッドを中断しようとすると、構文エラーが発生します

タイプ Thread から非静的メソッド interrupt() への静的参照を作成できません

また、ブール値を揮発性にすると、スレッドはまだ実行されています。

4

4 に答える 4

2

stop次のように宣言する必要がありますvolatile

static volatile boolean stop = false;

基本的に、フィールドにvolatileアクセスするすべてのスレッドvolatileは、(潜在的に)キャッシュされた値を使用する代わりに、続行する前に現在の値を読み取ることを意味しstopます。他の値を書き込みます。

于 2013-11-09T23:12:22.903 に答える
2

b.readLine()そのコード行により、入力が利用可能になるまでスレッドの実行が停止するため、スレッドはブロックされています。

停止を「強制」するには、次を使用しますThread.interrupt()

例えば:

stopChecking.addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {

        //To clarify the following uses a INSTANCE of CheckFiles, called CheckFiles.
        //In other words, somewhere there was a declaration with the format:
        // CheckFiles CheckFiles = ...

        CheckFiles.stop = true;
        CheckFiles.interrupt(); //Or whatever the name of your thread instance is
        System.out.println(CheckFiles.stop); //Prints true when pressed

    }
});

内部読み取りループも次のように変更する必要があります。

while(!stop && (line = b.readLine()) != null){
    Ststem.out.println(line);
}

割り込みは単に I/O のブロックを解除するだけなので、false別のブロッキング読み取りを行う前に、stop がまだ残っているかどうかを確認する必要があります。

b.close()他の人が示唆しているように、別の方法は、設定後に直接呼び出すことですstop = true;


編集:

Vakh が言ったvolatileように、変数の更新がstopすべてのスレッドにすぐに表示されるように、ブール値も作成する必要があります。

于 2013-11-09T23:12:23.280 に答える