2017-09-05 14 views
2

何とか今何時間かgroovyで作業しているスレッドの単純な割り込みを取得しようとしています。GroovyでJavaスレッドの割り込みがうまくいきません。(Groovyで)

次のコードは、スレッド 'name'に 'interrupted'フラグを設定しません。ループが終わりまで実行されるようにします。

通常、Thread.currentThread().isInterrupted()のチェックが欠けていた他にも数多くの質問がありました。しかし、これは、ここでそうではありません。

def t = Thread.start('name') { 
    try { 
     for (int i = 0; i < 10 && !Thread.currentThread().isInterrupted(); ++i) { 
      println "$i" 
      sleep 1000 
     } 
    } catch (InterruptedException e) { 
     println "Catched exception" 
     Thread.currentThread().interrupt(); 
    } 
} 
println "Interrupting thread in 1..." 
sleep 1000 
println "Interrupting thread..." 
t.interrupt() 
sleep 2000 

私は、次の取得の出力

Interrupting thread in 1... 
0 
Interrupting thread... 
1 
2 
3 
4 
5 
6 
7 
8 
9 

私が間違っているの/ここで欠場だろうか? また、ExecutorServiceを使用して、返されたFutureにcancel(true)を呼び出してみました。どちらもうまくいきませんでした。

答えて

3

TL; DR:は停止基準としてThread中断を使用しますが、代わりにいくつかのカスタムフラグを使用しないでください。あなたはInterruptedExceptionを投げることになるThread.sleep()を使用していない


が、中断を処理し、無視GDKs Object.sleep()http://docs.groovy-lang.org/docs/groovy-2.4.7/html/groovy-jdk/java/lang/Object.html#sleep(long)

のどちらかのような代わりにThread.sleep()を使用します(catchブロックで中断すると、あなたの場合には役に立たない)

def t = Thread.start('name') { 
    try { 
     for (int i = 0; i < 10 && !Thread.interrupted(); ++i) { 
      println i 
      Thread.sleep 1000 
     } 
    } catch (InterruptedException e) { 
     println "Catched exception" 
    } 
} 
println "Interrupting thread in 1..." 
sleep 1000 
println "Interrupting thread..." 
t.interrupt() 

Object.sleep()のバリアントをClosureで使用し、その中でループを中断します。 g。以下のようなInterruptedExceptionを投げて:あなたの混乱を解決した

def t 
t = Thread.start('name') { 
    try { 
     for (int i = 0; i < 10 && !Thread.interrupted(); ++i) { 
      println i 
      sleep(1000) { 
       throw new InterruptedException() 
      } 
     } 
    } catch (InterruptedException e) { 
     println "Catched exception" 
    } 
} 
println "Interrupting thread in 1..." 
sleep 1000 
println "Interrupting thread..." 
t.interrupt() 

、今あなたがやろうとしている何をしていない私にアドバイスをしましょう。割り込みは、中断状態としての使用のための良い方法ではありません。スリープまたはブロックIOは、さまざまな理由によりいつでも中断することができます。はるかに良い方法は、あなたの実行ループチェックを、作業を中止するためにトグルする一部のbooleanフラグにすることです。

+0

詳細な説明をありがとうございます。最初の場所では、カスタムフラグを使用して作業していたことに注意してください。しかし、ネットを検索した後、スレッドの実行を中止するために組み込みの割り込み機能を使用すべきであることを伝えるポストが多数見つかりました。しかしおそらくそれはjavaのためのものです。ちょうど解明のために:私は1つのスレッドで書かれ、別のスレッドで読み込まれているフラグの同期に関しては問題に遭遇しませんか? –

+0

ここでJavaやGroovyの違いはありません。私のアドバイスは実際にはJava用ですが、Java上に構築されているGroovyについても同じです。実際には、スレッドの執筆者とタスクは、徹底的に記述されテストされているため、できる限り使用する方が良いです。しかし、はい、安全に変更して複数のスレッドからアクセスできるようにするには、もちろんフラグ変数へのアクセスを同期させる必要があります。 – Vampire

4

sleepの間にスレッドを中断すると、中断スレッドがInterruptedExceptionでスローされ、中断された状態はクリアされます。したがって、Thread.currentThread().isInterrupted()は常にfalseを返します。

sleep 1000Thread.sleep(1000)に置き換えてコードを動作させることができます。

関連する問題