Executors.newSingleThreadExecutor()
から返されたExecutorService
を使用する場合、どのようにして中断できますか?
これを行うには、submit()
を呼び出すのではなく、_ execute()
ExecutorService
へのタスクを実行する必要があります。これを行うと、スケジュールされたタスクを操作するために使用できるFuture
が返されます。特に、関連するFuture
で cancel(true)
を呼び出して、現在実行中のタスクを中断できます(または、タスクが実行を開始していない場合は、実行を完全にスキップできます)まだ)。
ちなみに、 Executors.newSingleThreadExecutor()
によって返されるオブジェクトは、実際にはExecutorService
です。
エグゼキューターの内部管理スレッドを中断する別の方法は、ExecutorService
でshutdownNow(..)
メソッドを呼び出すことです。ただし、@ ericksonのソリューションとは対照的に、これによりThreadPoolExecutor
全体が今後の使用に適さなくなることに注意してください。
このアプローチは、ExecutorService
が不要になり、Future
インスタンスのタブを維持する必要がない場合に特に便利です(これの主な例はexit(..)
です)アプリケーションのメソッド)。
ExecutorService#shutdownNow(..)
javadocsからの関連情報:
アクティブに実行されているすべてのタスクの停止を試み、待機中のタスクの処理を停止し、実行を待機していたタスクのリストを返します。
アクティブに実行しているタスクの処理を停止するベストエフォート型の試み以外の保証はありません。たとえば、典型的な実装はThread.interruptを介してキャンセルされるため、割り込みに応答しないタスクは決して終了しない場合があります。
適切な方法の1つは、executorserviceのThreadFactoryをカスタマイズ/注入することであり、スレッドファクトリ内からスレッドのハンドルを作成し、タスクをスケジュールして、関心のあるスレッドに割り込むことができます。
ThreadFactoryの上書きされたメソッド「newThread」のデモコード部分:
ThreadFactory customThreadfactory new ThreadFactory() {
public Thread newThread(Runnable runnable) {
final Thread thread = new Thread(runnable);
if (namePrefix != null) {
thread.setName(namePrefix + "-" + count.getAndIncrement());
}
if (daemon != null) {
thread.setDaemon(daemon);
}
if (priority != null) {
thread.setPriority(priority);
}
scheduledExecutorService.schedule(new Callable<String>() {
public String call() throws Exception {
System.out.println("Executed!");
thread.interrupt();
return "Called!";
}
},
5,
TimeUnit.SECONDS);
return thread;
}
}
次に、以下を使用してexecutorserviceインスタンスを作成できます。
ExecutorService executorService = Executors.newFixedThreadPool(3,
customThreadfactory);
次に、5秒後に、executorserviceのスレッドに割り込み信号が送信されます。