【问题标题】:Java Timer is waiting for Task to finish before next Task startsJava Timer 正在等待 Task 在下一个 Task 开始之前完成
【发布时间】:2016-01-19 20:21:36
【问题描述】:

我有这个简单的应用程序

package testy;

import java.util.Timer;
import java.util.TimerTask;
import static testy.Test.log;

public class Test {

/**
 * @param args the command line arguments
 */
public static void main(String[] args) throws InterruptedException {
    Timer timer = new Timer(true);
    log("tasks start");
    timer.schedule(new Task1(), 1,120000);
    timer.schedule(new Task2(), 3000,120000);
    timer.schedule(new Task3(), 6000,120000);

    Thread.sleep(99999999L);
}

static void  log(String text) {
    System.out.println(text);
}
}

class Task1 extends TimerTask {
    @Override
    public void run() {
        log("Task1 start");
        try {
            Thread.sleep(12000L);
        } catch (InterruptedException ex) {
            log("interupted");
        }
        log("Task1 end");
    }
}

class Task2 extends TimerTask {
    @Override
    public void run() {
        log("Task2 start");
        try {
            Thread.sleep(12000L);
        } catch (InterruptedException ex) {
            log("interupted");
        }
        log("Task2 end");
    }
}

class Task3 extends TimerTask {
    @Override
    public void run() {
        log("Task3 start");
        try {
            Thread.sleep(12000L);
        } catch (InterruptedException ex) {
            log("interupted");
        }
        log("Task3 end");
    }
}

从这段代码中,我希望 Task1 将立即被触发,而 Task2 将在 3 秒后被触发(正如延迟时间所说)。但是会发生什么是 Task2 正在等待 Task1 完成并在此之后立即被解雇。日志:

tasks start
Task1 start
Task1 end
Task2 start
Task2 end
Task3 start
Task3 end
Task1 start
Task1 end
Task2 start
Task2 end
Task3 start
Task3 end

据我了解 Java Timer,任务应该独立触发。为什么这个应用程序的行为是不同的?如何在给定的时间精确地实现启动任务,而不关心 Timer1 是否完成?

感谢您的帮助!

【问题讨论】:

    标签: java asynchronous timer


    【解决方案1】:

    Timer 使用单线程。当你调用Thread.sleep(12000L);时,该线程被阻塞,无法执行其他任务。尝试使用ScheduledExecutorService 实现来代替使用更大的线程池。你可以用这个创建一个简单的线程池:

    java.util.concurrent.Executors.newScheduledThreadPool(corePoolSize)
    

    【讨论】:

      【解决方案2】:

      引用Javadoc

      与每个 Timer 对象对应的是一个后台线程,用于按顺序执行所有计时器的任务。

      如果您想要使用Timer 描述的行为,则需要多个Timer 实例。

      【讨论】:

      • 我明白我当时弄错了定时器的想法。由于文档引用,将此标记为答案。非常感谢!
      猜你喜欢
      • 1970-01-01
      • 2014-01-24
      • 1970-01-01
      • 2020-06-18
      • 2012-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多