1

コントローラーと何らかの作業を行うスレッドがあります。コントローラーには、緊急時にスレッドを遮断する割り込み機能があります。

私のコードのスケルトンは次のようになります。

public class SomeController{

private Thread th;
public SomeController(){
    th = null;
}
public void Input(int state){
    switch(state){
    case 0: //emergency shut off
        if(th != null){
            th.sleep(1000); //make thread sleep first, still no effect
            th.interrupt();
         }
        break;
    case 1: //thread creation
        th = new Thread(new Runnable(){
            public void run(){
                try{
                    DoSomeWork();
                    }
                catch(InterruptedException e)
                {
                    EmergencyProcedures();
                }
            }
            });
        th.start();
        break;
    }
}

ただし、割り込みが呼び出されると、InterruptedException がキャッチされることはありません。ここで何が間違っていますか?

4

6 に答える 6

4

頭に浮かぶ唯一の可能性:

  • スレッドを中断していません (本当にth.interrupt()呼び出されていますか?)
  • あなたは別のスレッドを中断します
  • スレッドは中断されますが、EmergencyProcedures には中断されていないと思わせる問題があります
  • スレッドを開始することはないため、スレッドを中断することはできません。
  • DoSomeWork()中断を無視します
于 2012-10-15T12:22:39.533 に答える
3

少なくともこれはあなたのコードの問題です:

th.sleep(1000); //make thread sleep first, still no effect

いいえ、別のスレッドをスリープ状態にすることはできません。現在のスレッドのみをスリープ状態にします。static sleepのインスタンスを介してメソッドを呼び出しているだけですThread

呼び出してth.interrupt()も、が自動的InterruptedExceptionに他のスレッド内にスローされることはありません。これは、スレッドのコードが割り込み可能なメソッド(宣言するメソッド)に入った場合にのみ発生しInterruptedExceptionます。

あなたの主な誤解は(おそらく)interruptメカニズムの性質にあります。stop非推奨のメカニズムとinterruptは異なり、協調的であるためオプションです。スレッドは割り込みシグナルのみを受信し、その状態を明示的にチェックする責任があります。信号に適切と思われる方法で応答できます。

于 2012-10-15T12:29:42.733 に答える
2

を正しく呼び出していると仮定するとth.interrupt();、妥当な時間内に割り込みが「認識」されていない場合に違いありません。interrupt()スレッドを呼び出した瞬間に魔法のように割り込みがスローされることはありません。一般的に言えば、スレッドは中断されたことを検出し、独自の をスローする必要がありますInterruptedException

現在、これは通常問題ではありません。他のいくつかの一般的に使用されるメソッドは、すぐThread.sleep()にスローするように設計されているためです。InterruptedException

時々手動で確認する必要がありThread.interrupted()ます。これにより、スレッドが中断されたかどうかがわかります。これにより、次のような構造が得られます。

if (Thread.interrupted()) {
    throw new InterruptedException();
}

中に入れるものDoSomeWork();

DoSomeWork(); 右に投げますInterruptedExceptionか?

于 2012-10-15T12:26:16.433 に答える
1

@assyliasが言ったように、またはスレッドが中断をサポートしていない場合は、 http://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.htmlの中断のサポートセクションを参照してください。基本的に、sleep や Thread.interrupted() など、割り込みをサポートするメソッドを使用する必要があります。

于 2012-10-15T12:22:00.953 に答える
0

睡眠が終わった後に中断していますか。ドキュメントに従って

このスレッドが Object クラスの wait()、wait(long)、または wait(long, int) メソッド、または join()、join(long)、join(long, int) の呼び出しでブロックされている場合、sleep(long)、または sleep(long, int)、このクラスのメソッドの場合、その割り込みステータスはクリアされ、InterruptedException を受け取ります。

于 2012-10-15T12:30:26.043 に答える
0

最初に作成したものを参照してくださいThread。ただし、開始していません。InterruptedException2 つ目は、 run メソッド内で例外をキャッチできないことです。スイッチ状態1でお試しください。

           th = new Thread(new Runnable(){
            public void run(){
                try{
                    System.out.println("Run");
                    Thread.sleep(10000);
                    }
                catch(InterruptedException e)
                {
                    EmergencyProcedures();
                }
            }
            });
于 2012-10-15T12:32:39.393 に答える