超时后中断任务的ExecutorService [英] ExecutorService that interrupts tasks after a timeout

查看:137
本文介绍了超时后中断任务的ExecutorService的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在寻找 ExecutorService 实现,可以提供超时。如果提交到ExecutorService的任务花费的时间超过运行超时,则会中断这些任务。实现这样的野兽不是这么艰巨的任务,但我想知道是否有人知道现有的实现。



这里是我想出了基于一些下面的讨论。任何评论?

  import java.util.List; 
import java.util.concurrent。*;

public 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< Runnable,ScheduledFuture>();

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

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

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

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

@Override
public void shutdown(){
timeoutExecutor.shutdown();
super.shutdown();
}

@Override
public List< Runnable> shutdownNow(){
timeoutExecutor.shutdownNow();
return super.shutdownNow();
}

@Override
protected void beforeExecute(Thread t,Runnable r){
if(timeout> 0){
final 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);
}
}

类TimeoutTask实现Runnable {
private final Thread thread;

public TimeoutTask(线程线程){
this.thread = thread;
}

@Override
public void run(){
thread.interrupt();
}
}
}


解决方案>

您可以使用
ScheduledExecutorService 。首先,你只能提交一次,开始immidiatly和保留创造的未来。之后,您可以提交一个新任务,在一段时间后取消保留的未来。

  ScheduledExecutorService executor = Executors.newScheduledThreadPool (2)。 
final Future handler = executor.submit(new Callable(){...});
executor.schedule(new Runnable(){
public void run(){
handler.cancel();
}
},10000,TimeUnit.MILLISECONDS) ;

这将执行你的处理程序(主要功能被中断)10秒,中断)该特定任务。


I'm looking for an ExecutorService implementation that can be provided with a timeout. Tasks that are submitted to the ExecutorService are interrupted if they take longer than the timeout to run. Implementing such a beast isn't such a difficult task, but I'm wondering if anybody knows of an existing implementation.

Here's what I came up with based on some of the discussion below. Any comments?

import java.util.List;
import java.util.concurrent.*;

public 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<Runnable, ScheduledFuture>();

    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;
    }

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

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

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

    @Override
    public void shutdown() {
        timeoutExecutor.shutdown();
        super.shutdown();
    }

    @Override
    public List<Runnable> shutdownNow() {
        timeoutExecutor.shutdownNow();
        return super.shutdownNow();
    }

    @Override
    protected void beforeExecute(Thread t, Runnable r) {
        if(timeout > 0) {
            final 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);
        }
    }

    class TimeoutTask implements Runnable {
        private final Thread thread;

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

        @Override
        public void run() {
            thread.interrupt();
        }
    }
}

解决方案

You can use a ScheduledExecutorService for this. First you would submit it only once to begin immidiatly and retain the future that is created. After that you can submit a new task that would cancel the retained future after some period of time.

 ScheduledExecutorService executor = Executors.newScheduledThreadPool(2); 
 final Future handler = executor.submit(new Callable(){ ... });
 executor.schedule(new Runnable(){
     public void run(){
         handler.cancel();
     }      
 }, 10000, TimeUnit.MILLISECONDS);

This will execute your handler (main functionality to be interrupted) for 10 seconds, then will cancel (i.e. interrupt) that specific task.

这篇关于超时后中断任务的ExecutorService的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆