5

これまでのところ、executorserviceを使った実験では、future.get、次にfuture.cancelを使用してスレッド割り込みをスローすることに関する多くのアドバイスがありました。この割り込みは、スレッドにキャッチされ、そこで処理される必要があります。私の質問は少し異なります。

実行時間の長さを追跡するだけのスレッドを実行していて、しきい値を超えた場合、これはexecutorserviceと実行中のすべてのスレッドを強制終了するための良い方法でしょうか?

思考プロセスの例:

ExecutorService threadPool = Executors.newFixedThreadPool(12);
timekeeper.start();
List<Future<?>> taskList = new ArrayList<Future<?>>();
    for (int i = 0; i < objectArray.length; i++) {
        Future<?> task = threadPool.submit(new ThreadHandler(objectArray[i], i));
        taskList.add(task);
        Thread.sleep(500);
    }

if(timekeeper.now() > 60)
    threadpool.shutdownNow();
}

これは機能しますか?スレッドが非常にまれに失敗するため、確認する方法がありません(約1/700の実行、および1日の特定の時間にのみ実行されます)。

4

2 に答える 2

4

これは私がすることです

ExecutorService threadPool = Executors.newFixedThreadPool(12);
List<Future<?>> taskList = new ArrayList<Future<?>>();
for (int i = 0; i < objectArray.length; i++) {
    taskList.add(threadPool.submit(new ThreadHandler(objectArray[i], i)));
threadPool.shutdown();
threadPool.awaitTermination(60, TimeUnit.SECONDS); // or what ever
threadPool.shutdownNow();

これは、タスクが割り込みを尊重することを前提としています。そうでない場合、スレッドを強制終了するクリーンな方法はありません(ほとんど同じものであるフラグを使用する場合を除く)


ここでThread.stop()を使用しない理由

  • stop()を呼び出すためのThreadオブジェクトにアクセスできません。
  • タスクがinterrupt()を無視すると、動作が悪くなる可能性があり、ヒープが破損した状態のままになる可能性があります。
  • stop()を呼び出すと、タスクは停止しますが、shutdown()トラップされたままでない限り、スレッドプールスレッドは停止しません。(確かに、回避するのは簡単です)
于 2012-10-18T13:33:58.480 に答える
4

このshutdownNowメソッドは、アクティブなすべてのタスクスレッドに割り込みを試みます。これは、タスクが尊重された割り込みにコーディングされている場合にのみ機能します。彼らはする必要があります:

  • 長時間実行ループで割り込みフラグが設定されているかどうかを確認し、

  • InterruptedExceptionsを正しく処理します。

基本的に、割り込みが機能するには、タスクが連携する必要があります。それらが協力しない場合、JVMを終了する以外に、それらを停止するための安全で信頼できる方法はありません。


上記の誰かが.stop()メソッドをコメントとして言及しましたが、なぜこれが悪い考えになるのかについてコメントを提供できますか?

このThread.stop()メソッドは基本的に安全ではないため、非推奨になりました。スレッドを停止すると、重要なデータ構造が中間状態のままになり、さまざまな方法でスレッドと対話していた他のスレッドに干渉する可能性があります。理論的にはstop安全に使用することは可能ですが、悪いことが起こらないようにするのに十分な一連の一般的な前提条件を理解することは困難です。

于 2012-10-18T13:37:34.923 に答える