TimerTask持续运行

发布于 2024-09-14 19:07:43 字数 781 浏览 10 评论 0原文

我对 Java 中 Timer 类的行为有疑问。 这是代码: http://pastebin.com/mqcL9b1n

public class Main {

    public static void main(String[] args) {
        Main m = new Main();
        m.foo();
        m = null;
    }

    public void foo() {
        Timer t = new Timer();
        t.schedule(new SysPrint(), 200);
    }

}

class SysPrint extends TimerTask {

    public void run() {
        System.out.println("Yes!");
    }
}

如果您运行该程序,会发生什么情况,它会打印“是的!”它不会做任何其他事情(程序不会结束)。

Java 文档说: 对 Timer 对象的最后一个实时引用消失并且所有未完成的任务都已完成执行后,计时器的任务执行线程将正常终止(并成为垃圾收集的对象)。

正如我所看到的,在“foo()”函数结束后,对 Timer 对象的“最后一个实时引用”就消失了。唯一安排的任务就是“是!”已执行的任务,所以我猜想在进程打印“是!”之后,Timer 对象应该结束并且进程应该终止。

这里发生了什么?

I have a question about the behaviour of Timer class in Java.
This is the code: http://pastebin.com/mqcL9b1n

public class Main {

    public static void main(String[] args) {
        Main m = new Main();
        m.foo();
        m = null;
    }

    public void foo() {
        Timer t = new Timer();
        t.schedule(new SysPrint(), 200);
    }

}

class SysPrint extends TimerTask {

    public void run() {
        System.out.println("Yes!");
    }
}

What happens is that if you run that program, it will print "Yes!" and it's not gonna do anything else (the program doesn't end).

The Java documentation says:
After the last live reference to a Timer object goes away and all outstanding tasks have completed execution, the timer's task execution thread terminates gracefully (and becomes subject to garbage collection).

As I see this thing, the "last live reference" to the Timer object is gone after the 'foo()' functions ends. And the only task scheduled was the "Yes!" task that was executed, so I guess that after the process printed "Yes!", the Timer object should end and the process should terminate.

What happened here?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

半葬歌 2024-09-21 19:07:43

Java 没有退出,因为运行计时器的线程仍在运行。在 Java 退出之前,您必须将该线程标记为守护线程。您可能无权访问线程本身,因此除非 Timer 有一种方法来标记它,否则您将很难做到这一点。您需要在finally 子句中手动停止它。

try {
   timer = new Timer();
   timer.schedule( new SysPrint(), 200 );
} finally {
   timer.cancel();
}

Java is not exiting because your thread running the Timer is still kicking around. You have to mark that thread as being a daemon thread before Java will exit. You probably don't have access to the thread itself so unless Timer has a method to mark it so you'll have a hard time doing that. You'll need to manually stop it in a finally clause.

try {
   timer = new Timer();
   timer.schedule( new SysPrint(), 200 );
} finally {
   timer.cancel();
}
梦中楼上月下 2024-09-21 19:07:43

我相信下面的代码应该可以解决问题。

public class Main {
  public static void main(String[] args) {
    Main m = new Main();
    m.foo();
    m = null;
  }

  public void foo() {
    Timer t = new Timer();
    t.schedule(new SysPrint(), 200);
  }
}

class SysPrint extends TimerTask {
  SysPrint(Timer timer) {
    this.timer = timer;
  }

  public void run() {
    System.out.println("Yes!");
    timer.cancel();
  }

  private Timer timer;
}

I believe the code below should do the trick.

public class Main {
  public static void main(String[] args) {
    Main m = new Main();
    m.foo();
    m = null;
  }

  public void foo() {
    Timer t = new Timer();
    t.schedule(new SysPrint(), 200);
  }
}

class SysPrint extends TimerTask {
  SysPrint(Timer timer) {
    this.timer = timer;
  }

  public void run() {
    System.out.println("Yes!");
    timer.cancel();
  }

  private Timer timer;
}
来世叙缘 2024-09-21 19:07:43

当您创建 Timer 对象时。创建一个 TimerThread。它是运行您的任务的内部线程。可以查看TimerThread的run()方法。你可以看到它有一个 while 循环。

 private void mainLoop() {
    while (true) {....

TimerThread没有设置为守护进程,因此main方法执行完全,jvm不存在。

这就是为什么你的程序总是运行并且不会停止。

When you create a Timer object. A TimerThread is created. And it the internal thread to run your task. You can view the method run() of TimerThread. You can see it has a while loop.

 private void mainLoop() {
    while (true) {....

The TimerThread not set to a daemon, so the main method execute completely, the jvm not exists.

That why your program is always running and don't stop.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文