ScheduledThreadPoolExecutor scheduleWithFixedDelay和"紧急"执行

use*_*166 6 java

我有以下问题,标准库不能很好地解决,我想知道是否有人在那里看到了另一个库,而不是可以做到这一点,所以我不需要一起破解自定义解决方案.我有一个使用scheduleWithFixedDelay()在线程池上安排的任务,我需要修改代码来处理与异步事件相关的任务"紧急"执行的请求.因此,如果任务计划在执行之间延迟5分钟,并且在最后一次完成执行后2分钟发生事件,我想立即执行任务,然后在完成后等待5分钟.在再次运行之前紧急执行.现在我能想到的最好的解决方案是让事件处理程序在scheduleWithFixedDelay()返回的ScheduledFuture对象上调用cancel()并立即执行任务,然后在任务中设置一个标志,告诉它重新安排自己具有相同的延迟参数.这个功能是否已经可用,我只是遗漏了文档中的内容?

vtr*_*kov 6

如果您正在使用ScheduledThreadPoolExecutor,则有一种方法decorateTask(实际上有两种方法,对于Runnable和Callable任务),您可以覆盖该方法以存储对某个任务的引用.

当您需要紧急执行时,您只需调用run()该引用,使其运行并重新安排,但具有相同的延迟.

一个快速的hack-up尝试:

public class UrgentScheduledThreadPoolExecutor extends
        ScheduledThreadPoolExecutor {
    RunnableScheduledFuture scheduledTask;

    public UrgentScheduledThreadPoolExecutor(int corePoolSize) {
        super(corePoolSize);
    }

    @Override
    protected  RunnableScheduledFuture decorateTask(Runnable runnable,
            RunnableScheduledFuture task) {
        scheduledTask = task;
        return super.decorateTask(runnable, task);
    }

    public void runUrgently() {
        this.scheduledTask.run();
    }
}

可以像这样使用:

public class UrgentExecutionTest {

    public static void main(String[] args) throws Exception {
        UrgentScheduledThreadPoolExecutor pool = new UrgentScheduledThreadPoolExecutor(5);

        pool.scheduleWithFixedDelay(new Runnable() {
            SimpleDateFormat format = new SimpleDateFormat("ss"); 

            @Override
            public void run() {
                System.out.println(format.format(new Date()));
            }
        }, 0, 2L, TimeUnit.SECONDS);
        Thread.sleep(7000);
        pool.runUrgently();
        pool.awaitTermination(600, TimeUnit.SECONDS);
    }
}

并产生以下输出:06 08 10 11 13 15