ホームページ > Java > &#&チュートリアル > ExecutorService で中断可能なタスクのタイムアウトを実装するにはどうすればよいですか?

ExecutorService で中断可能なタスクのタイムアウトを実装するにはどうすればよいですか?

DDD
リリース: 2024-12-11 14:54:11
オリジナル
831 人が閲覧しました

How Can I Implement a Timeout for Interruptable Tasks in an ExecutorService?

割り込み可能なタスクのタイムアウトを備えた ExecutorService

タスクを同時に実行する場合、多くの場合、指定された時間を超えるタスクを適切に中断するメカニズムを持つことが望ましいです。タイムアウト。これは、長時間実行されるタスクがアプリケーションのロックアップやパフォーマンスの問題を引き起こす可能性がある状況で特に役立ちます。

TimeoutExecutorService の実装

ここでは、TimeoutThreadPoolExecutor の実装を拡張して、標準の ThreadPoolExecutor とタイムアウトを組み込む機能:

class TimeoutThreadPoolExecutor extends ThreadPoolExecutor {

    private final long timeout;
    private final TimeUnit timeoutUnit;

    private final ScheduledExecutorService timeoutExecutor = Executors.newSingleThreadScheduledExecutor();
    private final ConcurrentMap<Runnable, ScheduledFuture> runningTasks = new ConcurrentHashMap<>();

    public TimeoutThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, long timeout, TimeUnit timeoutUnit) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue);
        this.timeout = timeout;
        this.timeoutUnit = timeoutUnit;
    }

    // Override methods to implement timeout behavior

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        if (timeout > 0) {
            ScheduledFuture scheduled = timeoutExecutor.schedule(new TimeoutTask(t), timeout, timeoutUnit);
            runningTasks.put(r, scheduled);
        }
    }

    @Override
    protected void afterExecute(Runnable r, Throwable t) {
        ScheduledFuture timeoutTask = runningTasks.remove(r);
        if (timeoutTask != null) {
            timeoutTask.cancel(false);
        }
    }

    // Timeout task to interrupt threads
    class TimeoutTask implements Runnable {

        private final Thread thread;

        public TimeoutTask(Thread thread) {
            this.thread = thread;
        }

        @Override
        public void run() {
            thread.interrupt();
        }
    }
}
ログイン後にコピー

使用法:

TimeoutThreadPoolExecutor を使用するには、タイムアウト値を指定してインスタンス化するだけです:

TimeoutThreadPoolExecutor executor = new TimeoutThreadPoolExecutor(
    4, // corePoolSize
    8, // maximumPoolSize
    1, // keepAliveTime
    TimeUnit.SECONDS, // timeUnit
    new LinkedBlockingQueue<>(), // workQueue
    5, // timeout
    TimeUnit.SECONDS // timeoutUnit
);
ログイン後にコピー

次に、タスクを実行者に次のように送信します。通常:

executor.submit(() -> {
    // long-running task
});
ログイン後にコピー

タスクが指定されたタイムアウトよりも長くかかる場合、タスクを実行しているスレッドが中断され、タスクが正常に終了します。

代替解決策

タスクのタイムアウトを実装するもう 1 つの方法は、「」で提案されているように、ScheduledExecutorService を使用することです。 応答。これには、タスクを Callable として送信し、作成された Future を保持することが含まれます。その後、一定期間後に将来のタスクをキャンセルするように 2 番目のタスクをスケジュールし、事実上タスクを中断できます。

以上がExecutorService で中断可能なタスクのタイムアウトを実装するにはどうすればよいですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート