A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 姚伟涛 中级黑马   /  2012-4-22 21:05  /  3398 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

  1. import java.util.*;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. import javax.swing.*;
  5. import javax.swing.Timer;

  6. public class TimerTest {
  7.     public static void main(String[] args) {
  8.      
  9.         TimerPrinter liPrinter = new TimerPrinter();
  10.         Timer t = new Timer(5000, liPrinter);
  11.          
  12.         t.start();
  13.          
  14.         JOptionPane.showMessageDialog(null, "Quit Program?");
  15.         System.exit(0);
  16.     }
  17. }

  18. class TimerPrinter implements ActionListener  
  19. {
  20.         static int it = 0;
  21.     public void actionPerformed(ActionEvent event) {
  22.          
  23.         Date now = new Date();
  24.         System.out.println("At the tone, the time is " + now + (it++));
  25.         Toolkit.getDefaultToolkit().beep();
  26.     }
  27. }
复制代码
我没有在main中明确取消掉timer,timer应该是被垃圾回收器取消的,但是垃圾回收器执行的时间又不确定,这是否能说明timer的实际被调用此书是不可控的,也就是不能说我main退出了,timer一定马上就不执行了?

2 个回复

倒序浏览
本帖最后由 杨国祯 于 2012-4-22 21:36 编辑

给你个建议,你启动多个线程,不是只是简单的执行这个程序,用这个单独的线程去监管这个Timer事件,
这样可以完美解决,同步问题,以及Timer的按时出现,另外比如我们手机上面的闹钟用的就是这种机制,特别是Android手机用的就是这种方法!

对于Timer的结束问题:
自动结束:
Timer 对象最后的引用完成后,并且 所有未处理的任务都已执行完成后,计时器的任务执行线程会正常终止(并且成为垃圾回收的对象)。但是这可能要很长时间后才发生。默认情况下,任务执行线程并不作为守护线程 来运行,所以它能够阻止应用程序终止。
主动结束:如果调用者想要快速终止计时器的任务执行线程,那么调用者应该调用Timer 的 cancel 方法。

(附)这些是API中这个类的方法
void cancel()           终止此计时器,丢弃所有当前已安排的任务。  
int purge()           从此计时器的任务队列中移除所有已取消的任务。  
void schedule(TimerTask task, Date time)           安排在指定的时间执行指定的任务。  
void schedule(TimerTask task, Date firstTime, long period)           安排指定的任务在指定的时间开始进行重复的固定延迟执行。  
void schedule(TimerTask task, long delay)           安排在指定延迟后执行指定的任务。
void schedule(TimerTask task, long delay, long period)           安排指定的任务从指定的延迟后开始进行重复的固定延迟执行。  
void scheduleAtFixedRate(TimerTask task, Date firstTime, long period)           安排指定的任务在指定的时间开始进行重复的固定速率执行。  
void scheduleAtFixedRate(TimerTask task, long delay, long period)           安排指定的任务在指定的延迟后开始进行重复的固定速率执行。

以上基本上可以实现你需要的功能! 手工请支持!

回复 使用道具 举报
本帖最后由 RWJ2012 于 2012-4-22 21:46 编辑

看了下Java1.6API,System类的exit方法描述如下:
public static void exit(int status)终止当前正在运行的 Java 虚拟机。参数用作状态码;根据惯例,非 0 的状态码表示异常终止。 该方法调用 Runtime 类中的 exit 方法。该方法永远不会正常返回。 调用 System.exit(n) 实际上等效于调用:
Runtime.getRuntime().exit(n)
再查看Runtime.exit(int)的方法描述:
通过启动虚拟机的关闭序列,终止当前正在运行的 Java 虚拟机。此方法从不正常返回。可以将变量作为一个状态码;根据惯例,非零的状态码表示非正常终止。
虚拟机的关闭序列包含两个阶段。在第一个阶段中,会以某种未指定的顺序启动所有已注册的关闭钩子 (hook)(如果有的话),并且允许它们同时运行直至结束。在第二个阶段中,如果已启用退出终结,则运行所有未调用的终结方法。一旦完成这个阶段,虚拟机就会暂停,如果在虚拟机已开始其关闭序列后才调用此方法,那么若正在运行关闭钩子,则将无限期地阻断此方法。如果已经运行完关闭钩子,并且已启用退出终结 (on-exit finalization),那么此方法将利用给定的状态码(如果状态码是非零值)暂停虚拟机;否则将无限期地阻断虚拟机。
     你编写的代码中:

System.exit(0) //表示正常终止虚拟机,将无限期地阻断虚拟机,导致虚拟机不能及时关闭。
可以将0改成任意非零数字(这里改为-1)即可将虚拟机强行关闭。改后的代码如下:
  1. import java.util.*;
  2. import java.awt.*;
  3. import java.awt.event.*;
  4. import javax.swing.*;
  5. import javax.swing.Timer;

  6. public class TimerTest {
  7. public static void main(String[] args) {

  8. TimerPrinter liPrinter = new TimerPrinter();
  9. Timer t = new Timer(5000, liPrinter);

  10. t.start();

  11. JOptionPane.showMessageDialog(null, "Quit Program?");
  12. System.exit(-1);
  13. }
  14. }

  15. class TimerPrinter implements ActionListener
  16. {
  17. static int it = 0;
  18. public void actionPerformed(ActionEvent event) {

  19. Date now = new Date();
  20. System.out.println("At the tone, the time is " + now + (it++));
  21. Toolkit.getDefaultToolkit().beep();
  22. }
  23. }
复制代码


这样,就可以关闭虚拟机,使整个程序终止。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马