3

私はいくつかのコードを持っています:

public class MyTask implements Runnable {
    @Override
    public void run() {
        // Some code

        Thread.sleep();

        // Some more code.
    }
}

ExecutorService executor = Executors.newCachedThreadPool();
List<MyTask> tasks = getTasks();
for(MyTask t : tasks)
    executor.execute(t);

executor.shutdownNow()
if(!executor.awaitTermination(30, TimeUnit.MINUTES)) {
    TimeoutException toExc = new TimeoutException("MyAPp hung after the 30 minutes timeout was reached.")   // TODO
    log.error(toExc)

    throw toExc
}

MyTaskから戻ってきた複数のインスタンスでこれを実行するとgetTasks()、非常に不思議になります。

[pool-3-thread-3] INFO me.myapp.MyTask - java.lang.InterruptedException: sleep interrupted
    at java.lang.Thread.sleep(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    ...etc.

ここでの問題は、根本的な原因がないことです。スレッドのスリープは、ある時点で「中断」されているだけです。

だから私は尋ねます:いつ/なぜThread.sleep()中断されたのか、そして例外の根本的な原因を突き止めるために何ができるでしょうか?

4

3 に答える 3

2

タスクが実行されているスレッドは、発行することで中断できます

future.cancel(true);

への呼び出しから返された Future オブジェクトに対してexecutorService.submit(runnable);

このような例外が多数発生する場合は、別の可能性として、executor サービス全体がシャットダウンされている可能性があります。

executorService.shutdownNow();

interruptedどのスレッドが実際にフラグをオンにしたかを直接調べる方法はありません。

于 2014-08-07T15:37:57.937 に答える
0

のJavaDocを参照するとThread.sleep()、別のスレッドがあなたのスレッドを中断しました。

例外:
InterruptedException - いずれかのスレッドが現在のスレッドを中断した場合。この例外がスローされると、現在のスレッドの中断ステータスがクリアされます。

詳細については、次のJavaDocを参照してください。InterruptedException

スレッドが待機中、スリープ中、または他の方法で占有されている場合にスローされ、アクティビティの前または最中にスレッドが中断されます。メソッドは、現在のスレッドが中断されたかどうかをテストし、中断された場合はすぐにこの例外をスローしたい場合があります。

于 2014-08-07T15:37:41.910 に答える
0

Runnableextendを実装する代わりに、ちょっとしたハックとしてThread。その後、呼び出しを転送する前に、オーバーライドinterruptしてスタック トレースを取得できます。

最終的なコードにはこれをお勧めしませんが、奇妙な割り込みを追跡する場合、これが唯一の方法かもしれません。

public class InterruptAwareThread extends Thread {
    volatile String interruptedStack = null;
    @Override
    public void interrupt () {
        StringWriter s = new StringWriter();
        new Exception().printStackTrace(new PrintWriter(s));
        interruptedStack = s.toString();
        super.interrupt();
    }
}
于 2014-08-07T16:22:40.520 に答える