web-dev-qa-db-ja.com

ExecutorServiceのスレッドを中断する方法

Executors.newSingleThreadExecutor()から返されたExecutorServiceを使用する場合、どのようにして中断できますか?

32
Ofek Ron

これを行うには、submit()を呼び出すのではなく、_ execute()ExecutorServiceへのタスクを実行する必要があります。これを行うと、スケジュールされたタスクを操作するために使用できるFutureが返されます。特に、関連するFuturecancel(true) を呼び出して、現在実行中のタスクを中断できます(または、タスクが実行を開始していない場合は、実行を完全にスキップできます)まだ)。

ちなみに、 Executors.newSingleThreadExecutor() によって返されるオブジェクトは、実際にはExecutorServiceです。

37
erickson

エグゼキューターの内部管理スレッドを中断する別の方法は、ExecutorServiceshutdownNow(..)メソッドを呼び出すことです。ただし、@ ericksonのソリューションとは対照的に、これによりThreadPoolExecutor全体が今後の使用に適さなくなることに注意してください。

このアプローチは、ExecutorServiceが不要になり、Futureインスタンスのタブを維持する必要がない場合に特に便利です(これの主な例はexit(..)です)アプリケーションのメソッド)。

ExecutorService#shutdownNow(..) javadocsからの関連情報:

アクティブに実行されているすべてのタスクの停止を試み、待機中のタスクの処理を停止し、実行を待機していたタスクのリストを返します。

アクティブに実行しているタスクの処理を停止するベストエフォート型の試み以外の保証はありません。たとえば、典型的な実装はThread.interruptを介してキャンセルされるため、割り込みに応答しないタスクは決して終了しない場合があります。

6
Priidu Neemre

適切な方法の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のスレッドに割り込み信号が送信されます。

0
wtsolid