簡體   English   中英

TimerTask 一直在運行

[英]TimerTask keeps running

我對 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 對象應該結束並且進程應該終止。

這里發生了什么?

Java 沒有退出,因為運行 Timer 的線程仍在運行。 在 Java 退出之前,您必須將該線程標記為守護線程。 您可能無權訪問線程本身,因此除非 Timer 有標記它的方法,否則您將很難做到這一點。 您需要在 finally 子句中手動停止它。

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

我相信下面的代碼應該可以解決問題。

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

當您創建一個 Timer 對象時。 創建一個 TimerThread。 它是運行您的任務的內部線程。 可以查看TimerThread的run()方法。 你可以看到它有一個 while 循環。

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

TimerThread 沒有設置為守護進程,因此 main 方法完全執行,jvm 不存在。

這就是為什么您的程序始終在運行並且不會停止的原因。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM