Home > Java > javaTutorial > How Can I Implement a Timeout for Interruptable Tasks in an ExecutorService?

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

DDD
Release: 2024-12-11 14:54:11
Original
864 people have browsed it

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

ExecutorService with Timeout for Interruptable Tasks

When executing tasks concurrently, it's often desirable to have a mechanism to gracefully interrupt tasks that exceed a specified timeout. This is particularly useful in situations where long-running tasks can lead to application lockups or performance issues.

Implementing a TimeoutExecutorService

Here's an implementation of a TimeoutThreadPoolExecutor that extends the standard ThreadPoolExecutor and incorporates a timeout feature:

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();
        }
    }
}
Copy after login

Usage:

To use the TimeoutThreadPoolExecutor, you can simply instantiate it with a timeout value:

TimeoutThreadPoolExecutor executor = new TimeoutThreadPoolExecutor(
    4, // corePoolSize
    8, // maximumPoolSize
    1, // keepAliveTime
    TimeUnit.SECONDS, // timeUnit
    new LinkedBlockingQueue<>(), // workQueue
    5, // timeout
    TimeUnit.SECONDS // timeoutUnit
);
Copy after login

Then, submit tasks to the executor as usual:

executor.submit(() -> {
    // long-running task
});
Copy after login

If a task takes longer than the specified timeout, the thread executing the task will be interrupted, causing the task to terminate gracefully.

Alternative Solution

Another approach to implementing a timeout for a task is to use the ScheduledExecutorService as suggested in the response. This involves submitting the task as a Callable and retaining the created future. A second task can then be scheduled to cancel the future after a certain period, effectively interrupting the task.

The above is the detailed content of How Can I Implement a Timeout for Interruptable Tasks in an ExecutorService?. For more information, please follow other related articles on the PHP Chinese website!

source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template