以下是代码:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.Timer;
public class TimerSample {
public static void main(String args[]) {
new JFrame().setVisible(true);
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("Hello World Timer");
}
};
Timer timer = new Timer(500, actionListener);
timer.start();
}
}
它会生成一个窗口,然后在终端(命令提示符)中定期打印“Hello World Timer”。如果我对此行new JFrame().setVisible(true);
发表评论,则应用程序不会向命令行打印任何内容。为什么呢?
增加:
我不确定我是否正确理解答案。据我所知,计时器启动一个新线程。并且这个新线程与“主”线程同时存在。当“主”线程完成时(当一切都完成并且没有任何事情可做)时,整个应用程序终止(与定时器创建的“新”线程一起)。对吗?
已添加2:
上述说明仍未解释所有内容。例如,如果我对new JFrame().setVisible(true);
发表评论并将try {Thread.sleep(20000);} catch(InterruptedException e) {};
放在timer.start()
之后,该计划就会有效。所以,我有点理解。使用sleep,我们保持“main”线程忙,这样定时器创建的线程就可以存在。但是new JFrame().setVisible(true);
并没有占据“主要”。据我所知,它创建了自己的线程(如Timer)。那么,为什么JFrame的线程可以在没有主线程和定时器线程的情况下存在呢?
答案 0 :(得分:5)
你错过了这一点。 Timer与您创建的窗口无关,当您注释掉该窗口创建行时,它也可以工作。
但是,您未能看到的是:您的主程序在timer.start()
之后退出,因此,您的程序执行被终止,并随之进入计时器。
如果最后添加Thread.sleep(20000);
(包括所需的异常处理),或者需要一些时间的任何其他代码,则可以验证这一点。然后,即使没有创建任何窗口,您的计时器也能正常工作。
关键是即使没有显示任何内容,JFrame仍然处于活动状态,这反过来会使您的计时器保持活动状态。
答案 1 :(得分:1)
在窗口事件循环中调用定时器函数(其中还包括调整大小,移动,重新绘制等内容)。显然,如果窗口被隐藏,则不会执行事件循环。
这是错的,请检查弗兰克的回答。
答案 2 :(得分:1)
对应每个Timer对象 一个单一的后台线程 用于执行所有计时器 任务,顺序。
在最后一次实时参考之后 定时器对象消失了 已完成的任务已完成 执行,计时器的任务执行 线程优雅地终止(和 变得垃圾 采集)。但是,这可以采取 任意长时间发生。默认情况下, 任务执行线程不运行 作为守护程序线程,所以它是有能力的 保持申请 终止。如果来电者想要 终止计时器的任务执行 线程很快,调用者应该 调用计时器的取消方法。1
那么java.util.Timer与你可能会问的javax.swing.Timer有什么关系呢?
在v 1.3中,另一个Timer类是 添加到Java平台: java.util.Timer中。它和 javax.swing.Timer提供相同的 基本功能2
因此,在您的计时器真正启动之前,您对计时器的最后一次引用就会消失...如果您在调用timer.start();
时注意到主要方法已完成,除非有某些内容将使你的主线程保持活动直到计时器启动,然后你的计时器可能永远不会启动。
在第一个示例中,JFrame
使主线程保持活动状态。
在第二个示例中,您睡眠时间足以让timer
启动,然后计时器会使主线程保持活动状态:
public static void main(String args[]) {
//new JFrame().setVisible(true);
ActionListener actionListener = new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
System.out.println("Hello World Timer");
}
};
Timer timer = new Timer(500, actionListener);
timer.start();
try {
Thread.sleep(500);//<--- the timer will still die
Thread.sleep(100);//<--- sleep for another 100 and the timer will start printing although you can't rely on it
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}