3

次のコードがあると仮定します。

while(!Thread.currentThread().isInterrupted()){  
    //do something   
    Thread.sleep(5000);  
}

ここThread.sleepで`InterruptedExceptionをスローするので、次のようになります。

while(!Thread.currentThread().isInterrupted()){  
   //do something   
   try{  
     Thread.sleep(5000);    
   } catch(InterruptedException e){  

   }
}

ヒットした場合catchwhileループは続行しますか、それとも実行する必要がありますThread.currentThread().interrupt()か?このメソッドを呼び出すと、それも原因になりませんInterruptedExceptionか?それ以外の場合、そもそもどのようにして例外を取得しましたか?

また、私が持っている場合:

while (!Thread.currentThread().isInterrupted()){  
   //do something   
   callMethod();  
}  

private void callMethod(){  
   //do something  
   try {  
     Thread.sleep(5000);    
   } catch(InterruptedException e){  

   }
}

再び私のwhileループは壊れますか?

4

3 に答える 3

2

実際、あなたの質問はtry - catch - finally マルチスレッドに関するものではありません。

1)sleepをスローするExceptionと、catchブロックが実行され、whileループが続行されます。

2)1)とまったく同じことをします

whileループを終了するには、次のようにします。

try{  
   while(!Thread.currentThread.isInterrupted){  
       //do something   
       Thread.sleep(5000);    
   }  
}
catch(InterruptedException e){  

}

その場合、Exceptionがスローされると、whileループが残り、catchブロックが実行されます。

于 2013-02-19T09:03:30.377 に答える
1

Thread.sleep()を投げる前に「中断されたステータス」をクリアしますInterruptedException。catchブロックを呼び出す必要がありますThread.currentThread().interrupt()。そうしないと、スレッドが戻るときに常に「中断されない」ため、while条件が成功しない可能性が高くなりcallMethodます。

例外はinterrupt()メソッドが原因ではなくsleep()、「中断された」と通知されたスレッドのブロックが原因です。これについては、ここで詳しく説明します。この回答も参照してください。

于 2013-02-19T09:29:55.240 に答える
1

スレッドで割り込みを呼び出しても、それ自体は例外をスローしません。割り込みフラグが設定されている間、スリープまたは待機すると、InterruptedExceptionがスローされます。

何がInterruptedExceptionをスローできるかは完全に予測可能であるため、中断されているスレッドが制御を持ち、応答方法を選択できます。これはチェックされた例外なので、何がそれをスローするかは明らかです。どこにでも投げることができるThreadDeathとは異なります。

InterruptedExceptionがスローされると、スレッドの中断ステータスがリセットされます。後でフラグをチェックしてtrueにしたいため、スレッドの中断ステータスを復元する場合は、を呼び出しThread.currentThread().interrupt()て設定します。

命令の処理方法を変更するために、中断中に異常なことは何も起こりません。したがって、ループでInterruptedExceptionをキャッチし、フラグをチェックして抜け出すことを選択した場合は、フラグをリセットする必要があります。

while(!Thread.currentThread().isInterrupted()){  
   //do something   
   try{  
     Thread.sleep(5000);    
   } catch(InterruptedException e){  
        Thread.currentThread().interrupt();
   }
}

または、InterruptedExceptionを使用して、ループから抜け出すこともできます。

try {
    while (!Thread.currentThread().isInterrupted()) {
        // do something
        Thread.sleep(5000);
    }
} catch (InterruptedException e) {
    // flag value is not used here, but still good style
    Thread.currentThread().interrupt(); 
}

この最後のスニペットが中断されているスレッドの実行メソッド全体である場合、中断されたステータスを再度設定しなくても問題はありませんが、他の部分でコンポーネントが使用されている場合は、動作の悪い部分が中断された部分をスケルチすることは望ましくありません。スレッド内の他のコードが中断を認識しないようにフラグを立てます。

于 2015-08-24T21:30:15.997 に答える