0

そこで、タスクハンドラーを介してオブジェクトの配列を送信するコードのブロックを作成しました。プログラムがクラッシュし、正しく閉じられなかったインスタンスが発生しました...このコードは、私が考えていることを実行しますか? ?

私の考えでは、次のコードはオブジェクトを取得してハンドラーに渡し、最大30秒が経過するまで待機し、そのスレッドが完了していない場合は強制終了する必要があります。右?

 //Iterate through the array to submit them into individual running threads.
    ExecutorService threadPool = Executors.newFixedThreadPool(12);
    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);
    }

    //Event handler to kill any threads that are running for more than 30 seconds (most threads should only need .25 - 1 second to complete.
    for(Future future : taskList){
        try{
            future.get(30, TimeUnit.SECONDS);
        }catch(CancellationException cx){ System.err.println("Cancellation Exception: "); cx.printStackTrace();
        }catch(ExecutionException ex){ System.err.println("Execution Exception: ");ex.printStackTrace();
        }catch(InterruptedException ix){ System.err.println("Interrupted Exception: ");ix.printStackTrace();
        }
    }
    threadPool.shutdown(); // SHUT. DOWN. EVERYTHING.
4

3 に答える 3

2

TimeoutException30秒以内に作業が完了しない場合にスローされます。スレッドをキャンセルするには、Future.cancel()を使用する必要があります。Futureで表される実行中のスレッドを中断します。

于 2012-10-02T13:50:46.073 に答える
2

プログラムがクラッシュし、正しく終了しませんでした

コメントから、プログラムがクラッシュするのではなくハングしたようです。将来の問題を説明するために正しい用語を使用してください。ある種のリモートWebリクエストが終了しなかったようです。可能であれば、すべてのhttp-clientおよびその他の接続にIOタイムアウトを設定してください。 NIO割り込み可能チャネルを使用していない限り、Web要求を停止しないthread.interrupt()可能性があります。

例えば:

HttpClientParams params = new HttpClientParams();
params.setSoTimeout(socketTimeoutMillis);
HttpClient httpClient = new HttpClient(params);

私の考えでは、次のコードはオブジェクトを取得してハンドラーに渡し、最大30秒が経過するまで待機し、そのスレッドが完了していない場合は強制終了する必要があります。右?

あなたのコードはそれを完全には行いません。

  • threadPool.shutdown()最後のタスクを送信した直後に電話する必要があります。スレッドプールは新しいタスクの受け入れを停止しますが、送信されたタスクは引き続き実行されます。
  • 30秒を超えて実行されているタスクを「強制終了」する場合は、を使用する必要があります。threadPool.shutdownNow()これにより、でまだ実行されているジョブが実際に中断されthreadPoolます。future.cancel()タイムアウト時に他の人が推奨しているように、個々のタスクを呼び出すこともできますget()
  • 割り込みを機能させるには、割り込みを確認できるようにThreadHandlerチェックThread.currentThread().isInterrupted()する必要があることに注意してください。中断すると、スリープ、待機、およびその他のメソッドもスローされInterruptedExceptionます。詳細については、ここで私の答えを参照してください。
于 2012-10-02T13:51:23.757 に答える
2
//Event handler to kill any threads that are running for more than 
//30 seconds (most threads should only need .25 - 1 second to complete.

いいえ、そうではありません。あなたは彼らがもう終わるのを待っているだけではありません。cancel永久にそれを殺すために使用します:

for(Future future : taskList){
    try{
        future.get(30, TimeUnit.SECONDS);
    }catch(TimeoutException ex) {
        future.cancel(true);
    }
}

また、呼び出し後にエグゼキュータが終了したことを確認する必要がありますshutdown

threadPool.shutdown();
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
于 2012-10-02T13:55:12.087 に答える