java - 在 java 中安排单线程重复运行,但如果上一次运行未完成则跳过当前运行

标签 java

有时重复任务的持续时间比它的周期长(在我的例子中,这可能一次发生几个小时)。想一想需要 7 分钟运行并计划每 10 分钟运行一次的重复任务,但有时连续几个小时每次运行需要 15 分钟。

Timer 和 ScheduledThreadPoolExecutor 类都有一个 scheduleAtFixedRate 方法,通常用于此类功能。但是,两者都有“落后就要 catch ”的特点。换句话说,如果 Timer 落后于几次执行,它会建立一个工作队列,该队列将连续工作,直到它 catch 运行次数,如果没有任何任务花费的时间超过指定期间。如果上一次运行未完成,我想通过跳过当前执行来避免这种行为。

我有一个解决方案,它涉及弄乱池化执行程序的 afterExecution 方法,重新计算延迟,并使用新的延迟重新安排可运行对象,但想知道是否有更简单的方法,或者此功能是否已经存在于某个地方的公共(public)图书馆。我知道安排固定延迟而不是固定时间,但这对我不起作用,因为尝试在固定时间执行任务很重要。有没有比我的 afterExecution 解决方案更简单的选项?

最佳答案

我认为您想要的是长时间运行的任务本身不在 ScheduledExecutorService 本身中运行,而是在后台线程中运行。然后固定速率任务将始终快速完成,因为它仅用于检查是否在后台启动实际任务(如果它仍在上次运行)。

ScheduledExecutorService executorService = Executors.newScheduledThreadPool(1);
final Runnable actualTask = null;

executorService.scheduleAtFixedRate(new Runnable() {
    private final ExecutorService executor = Executors.newSingleThreadExecutor();
    private Future<?> lastExecution;
    @Override
    public void run() {
        if (lastExecution != null && !lastExecution.isDone()) {
            return;
        }
        lastExecution = executor.submit(actualTask);
    }
}, 10, 10, TimeUnit.MINUTES);

关于java - 在 java 中安排单线程重复运行,但如果上一次运行未完成则跳过当前运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11944688/

相关文章:

java - gephi 0.9.1 的 OpenOrd 布局

java - 我应该如何修复这个字体加载器?

java - Android如何搜索对GitHub的依赖关系?

java - JAVA程序如何结合Http header和read content?

java - Netty 工作线程和吞吐量

java - 将内联元素列表直接反序列化为列表

java - Hibernate 获取数据 .list() 已不再使用且表未映射。该怎么办?

java - derby + hibernate ConstraintViolationException 使用多对多关系

java - 根据不同的id开头从数据库更改密码

java - 升级到 Ubuntu 14.04 后,JRE 在 Eclipse 中崩溃