-1

質問の短いバージョンがあります:

  1. 私はそのようなスレッドを開始します:counter.start();、ここcounterでスレッドです。
  2. スレッドを停止したい時点で、次のようにします。counter.interrupt()
  3. 私のスレッドでは、定期的にこのチェックを行いますThread.interrupted()trueそれがスレッドから私を与えreturn、その結果、それが停止した場合。

そして、必要に応じて、ここにいくつかの詳細があります:

詳細が必要な場合は、こちらをご覧ください。ディスパッチスレッドの発明から、次のようにカウンタースレッドを開始します。

public static void start() {
    SwingUtilities.invokeLater(new Runnable() {
        public void run() {
            showGUI();
            counter.start();
        }
    });
}

スレッドは次のように定義されています。

public static Thread counter = new Thread() {
    public void run() {
        for (int i=4; i>0; i=i-1) {
            updateGUI(i,label);
            try {Thread.sleep(1000);} catch(InterruptedException e) {};
        }
            // The time for the partner selection is over.
        SwingUtilities.invokeLater(new Runnable() {
                public void run() {    
                frame.remove(partnerSelectionPanel);
                frame.add(selectionFinishedPanel);
                frame.invalidate();
                frame.validate();
            }
        });
    }
};

スレッドは「最初の」ウィンドウでカウントダウンを実行します(ホームに残っている時間が表示されます)。時間制限が過ぎた場合、スレッドは「最初の」ウィンドウを閉じて、新しいウィンドウを生成します。次のようにスレッドを変更したい:

public static Thread counter = new Thread() {
    public void run() {
        for (int i=4; i>0; i=i-1) {
            if (!Thread.interrupted()) {
                updateGUI(i,label);
            } else {
                return;
            }
            try {Thread.sleep(1000);} catch(InterruptedException e) {};
        }
        // The time for the partner selection is over.
        if (!Thread.interrupted()) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {    
                frame.remove(partnerSelectionPanel);
                frame.add(selectionFinishedPanel);
                frame.invalidate();
                frame.validate();
            }
        });
        } else {
            return;
        } 
    }
};

追加した:

いくつかの理由で動作しません。スレッドを中断するメソッドがあります:

public static void partnerSelected() {
    System.out.println("The button is pressed!!!!");
    counter.interrupt();
}

このメソッドは、ボタンが押されたときにアクティブになります。ボタンを押すと、ターミナルに対応する出力が表示されます(したがって、このメソッドがアクティブになり、何かが実行されます)。しかし、いくつかの理由により、スレッドを中断しません。スレッドのコードは次のとおりです。

public static Thread counter = new Thread() {
    public void run() {
        for (int i=40; i>0; i=i-1) {
                if (Thread.interrupted()) {
                    System.out.println("Helloo!!!!!!!!!!!!!!!");
                    return;
                }
            updateGUI(i,label); 
            try {Thread.sleep(1000);} catch(InterruptedException e) {};
        }
            // The time for the partner selection is over.
            if (Thread.interrupted()) {
                System.out.println("Helloo!!!!!!!!!!!!!!!");
                return;
            }
        SwingUtilities.invokeLater(new Runnable() {
                public void run() {    
                frame.remove(partnerSelectionPanel);
                frame.add(selectionFinishedPanel);
                frame.invalidate();
                frame.validate();
            }
        });
    }
};

PS「こんにちは!!!!!!!!!!!!!」が表示されません ターミナルで...

4

5 に答える 5

5

正しい考えにかなり近い。ただし、次のようにcatch (InterruptedException)する必要があります。

Thread.currentThread().interrupt();

中断されたステータスが再び継続し、2番目のブロックの処理を実行しないようにします。


私のポイントを明確にするために編集します(OPの編集が私の最初のポイントを見逃しているように見えるため:-P):次のようにコードを書く必要があります:

try {
    for (int = 40; i > 0; --i) {
        updateGUI(i, label);
        Thread.sleep(1000);
    }
} catch (InterruptedException e) {
    Thread.currentThread().interrupt();  // <-- THIS LINE IS IMPORTANT
}

中断が何をするかを説明するための2番目の編集。:-)

を呼び出すとthread.interrupt()、そのスレッドの中断フラグが設定されます。そのフラグはそれ自体では何もしません。それは単なる変数です。これは、割り込みが「協​​調スレッド管理」と呼ばれるものをサポートしているためです。この場合、スレッドの実行中のコードが、(その場で強制的に終了するのではなく)割り込み時に何をするかを決定します。

JDKに組み込まれている、、、、、などの一部の関数Thread.sleepObject.waitフラグLock.lockInterruptiblyチェックInterruptedExceptionし、設定されている場合は、フラグをクリアした後にをスローします。

したがって、これらの関数の1つを呼び出す場合は、中断されたフラグを手動でチェックする必要はありません。ただし、そうでない場合、たとえば、何かを待つのではなく集中的な処理を行っている場合は、フラグを定期的にチェックする必要があります。

フラグを確認する方法は2つあります。

  1. interrupted()
  2. isInterrupted()

最初のものは、中断されたフラグをクリアします。2番目のものはそうではありません。アプリケーションロジックにとって「より正しい」バージョンを決定する必要があります。

于 2010-03-21T18:27:27.367 に答える
1

JavaSpecialistsニュースレターのこの記事をチェックしてください。この記事では、interrupt()これを適切にスレッド化および管理する方法について説明しています。

于 2010-03-21T18:32:23.707 に答える
0

はい、それは行く方法です

于 2010-03-21T18:25:38.960 に答える
0

私は編集し、今日ここでレッスンを学んだことに注意したいと思います。次の2つの段落で説明するように、ブール値を実装する理由はありません。割り込みメカニズムは私のためにそれを行います。何らかの理由で、「interrupt」がそのトラックでスレッドを停止させると思っていました(isInterrupted()が何をしたと思ったかはわかりません!)。

だから、ここにすべきでないことの例があります。割り込みテクニックを使い続けてください!

(私に反対票を投じないでください...)


私は割り込みを避ける傾向がありますが、特にスレッドを停止する傾向があります。あなたの場合、stop()の代わりにinterrupt()を使用しようとしていますが、これは正当な理由で非推奨になっています。スレッドがカウントを停止する必要があるかどうかを表すブール値を宣言し、スレッドにそのブール値を継続的にチェックさせるだけです。次に、親スレッドがカウンターを停止する準備ができたら、ブール値をtrue(停止)に設定する必要があります。これにより、カウンタースレッドは、値を再度確認するとすぐに停止します。

カウンタースレッドの匿名クラス定義に、を追加しpublic volatile boolean shouldStop;ます。の先頭にrun()、を設定しshouldStop = false;ます。Thread.interrupted()次に、すべてをshouldStopifステートメント内の)に置き換えます。最後に、を呼び出す代わりにcounter.interrupt()、と言うだけcounter.shouldStop = true;です。続行する前にカウンターが停止していることを確認したい場合はcounter.join()、設定直後に追加で呼び出すことができます。shouldStop=true

于 2010-03-21T18:27:03.660 に答える
0
  1. この目的のために個別の揮発性変数(ブールisStopped)を使用することはより良い方法(リンク)と考えられています。

  2. interrupted()スレッドが中断された場合、メソッドが値をtrueからfalseに変更するとします。

System.out.println (Thread.interrupted()); //true

System.out.println (Thread.interrupted()); //false

別の方法はisInterrupted()方法です。

于 2010-03-21T18:29:19.973 に答える