shutdownNow()
またはshutdown()
を呼び出すたびにシャットダウンしません。私は、シャットダウンが保証されていないことを言っているいくつかのスレッドを読みました。
典型的なパターンは次のとおりです。
_executorService.shutdownNow();
executorService.awaitTermination();
_
shutdownNow
を呼び出すと、executorは(一般に)管理するスレッドを中断しようとします。シャットダウンを正常に行うには、スレッドで割り込み例外をキャッチするか、割り込みステータスを確認する必要があります。そうしないと、スレッドは永久に実行され、エグゼキューターはシャットダウンできなくなります。これは、Javaでのスレッドの中断は協調プロセスであるためです(つまり、interruptedコードは、interrupting)ではなく、停止を要求されたときに何かを行う必要がありますコード)。
たとえば、次のコードは_Exiting normally...
_を出力します。ただし、行if (Thread.currentThread().isInterrupted()) break;
をコメント化すると、executor内のスレッドがまだ実行されているため、_Still waiting...
_が出力されます。
_public static void main(String args[]) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable() {
@Override
public void run() {
while (true) {
if (Thread.currentThread().isInterrupted()) break;
}
}
});
executor.shutdownNow();
if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) {
System.out.println("Still waiting...");
System.exit(0);
}
System.out.println("Exiting normally...");
}
_
あるいは、次のようにInterruptedException
で書くこともできます。
_public static void main(String args[]) throws InterruptedException {
ExecutorService executor = Executors.newFixedThreadPool(1);
executor.submit(new Runnable() {
@Override
public void run() {
try {
while (true) {Thread.sleep(10);}
} catch (InterruptedException e) {
//ok let's get out of here
}
}
});
executor.shutdownNow();
if (!executor.awaitTermination(100, TimeUnit.MICROSECONDS)) {
System.out.println("Still waiting...");
System.exit(0);
}
System.out.println("Exiting normally...");
}
_
最良の方法は、javadocに実際にあるものです:
次のメソッドは、2つの段階でExecutorServiceをシャットダウンします。最初に
shutdown
を呼び出して着信タスクを拒否し、次に必要に応じてshutdownNow
を呼び出して残留タスクをキャンセルします:
void shutdownAndAwaitTermination(ExecutorService pool) {
pool.shutdown(); // Disable new tasks from being submitted
try {
// Wait a while for existing tasks to terminate
if (!pool.awaitTermination(60, TimeUnit.SECONDS)) {
pool.shutdownNow(); // Cancel currently executing tasks
// Wait a while for tasks to respond to being cancelled
if (!pool.awaitTermination(60, TimeUnit.SECONDS))
System.err.println("Pool did not terminate");
}
} catch (InterruptedException ie) {
// (Re-)Cancel if current thread also interrupted
pool.shutdownNow();
// Preserve interrupt status
Thread.currentThread().interrupt();
}
}