`
dianziermu
  • 浏览: 137502 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

使用java.util.Timer 分享修改删除

    博客分类:
  • J2SE
阅读更多

在应用开发中,经常需要一些周期性的操作,比如每5分钟检查一下新邮件等。对于这样的操作最方便、高效的实现方式就是使用java.util.Timer工具类。比如下面的代码每5分钟检查一遍是否有新邮件:

  1.         private  java.util.Timer  timer;
  2.         timer = new  Timer (true );
  3.         timer.schedule(new  java.util.TimerTask () {
  4.             public  void  run() {
  5.                     //server.checkNewMail(); 检查新邮件
  6.             }
  7.         }, 0, 5*60*1000);


使用这几行代码之后,Timer本身会每隔5分钟调用一遍server.checkNewMail()方法,不需要自己启动线程。Timer本身也是多线程同步的,多个线程可以共用一个Timer,不需要外部的同步代码。
    在《The Java Tutorial》中有更完整的例子:

  1. public  class  AnnoyingBeep {
  2.     Toolkit  toolkit;
  3.     Timer  timer;
  4.     public  AnnoyingBeep() {
  5.     toolkit = Toolkit .getDefaultToolkit();
  6.         timer = new  Timer ();
  7.         timer.schedule(new  RemindTask(),
  8.                    0,        //initial delay
  9.                    1*1000);  //subsequent rate
  10.     }
  11.     class  RemindTask extends  TimerTask  {
  12.     int  numWarningBeeps = 3;
  13.         public  void  run() {
  14.         if  (numWarningBeeps > 0) {
  15.             toolkit.beep();
  16.         System .out.println("Beep!" );
  17.         numWarningBeeps--;
  18.         } else  {
  19.             toolkit.beep(); 
  20.                 System .out.println("Time's up!" );
  21.             //timer.cancel(); //Not necessary because we call System.exit
  22.             System .exit(0);   //Stops the AWT thread (and everything else)
  23.         }
  24.         }
  25.     }
  26.     ...
  27. }

这段程序,每隔3秒响铃一声,并打印出一行消息。循环3次。程序输出如下:
Task scheduled.
Beep!      
Beep!      //one second after the first beep
Beep!      //one second after the second beep
Time's up! //one second after the third beep

Timer类也可以方便地用来作为延迟执行,比如下面的代码延迟指定的时间(以秒为单位)执行某操作。类似电视的延迟关机功能。

  1. ...
  2. public  class  ReminderBeep {
  3.     ...
  4.     public  ReminderBeep(int  seconds) {
  5.     toolkit = Toolkit .getDefaultToolkit();
  6.         timer = new  Timer ();
  7.         timer.schedule(new  RemindTask(), seconds*1000);
  8.     }
  9.     class  RemindTask extends  TimerTask  {
  10.         public  void  run() {
  11.             System .out.println("Time's up!" );
  12.         toolkit.beep();
  13.         //timer.cancel(); //Not necessary because we call System.exit
  14.         System .exit(0);   //Stops the AWT thread (and everything else)
  15.         }
  16.     }
  17.     ...
  18. }


===========================================================

一些注意的问题:

1. 如果希望自己的Task一直运行,而不是像上面的RemindTask那样仅循环3次。
这 很简单,Task仅代表了一次的动作。而不是让Task完成循环。上面的RemindTask中之所以有一个计数,是因为要运行3次停止,如果需要一直保 持运行。把上面有关的计数的代码全部去除即可。其实Timer中并没有提供运行指定次数后即停止的机制,所以,上面的计数满足了这个功能需要。

2. 能否设置Timer的优先级?
Timer 中是利用一个线程来进行计时及周期触发动作的。现在的Timer实现中并没有提供设置优先级的方法,在你调用new Timer()时线程已经启动,所 以,除非Timer的以后版本中在构造方法中增加优先级参数,否则,我们是不能控制其优先级的。现在的Timer默认是在 Thread.NORM_PRIORITY优先级下运行的。但是Timer提供了一个Timer(boolean isDaemon)的构造方法,可以将 Timer设置为daemon线程。这样,在你的程序中其它线程都运行完毕后,程序就可以退出了。

3. Timer是不是实现了精确地定时?
否。Timer中也是采用Object.wait(long time)来实现定时的,由于Object.wait()不保证精确计时,所以Timer也不是一个精确的时钟。如果是实时系统,不能依赖Timer。

4. 假如在一个Timer类里面再定义一个Timer类,外层定义的时间是24小时循环一次,而内层定义的是1小时循环一次,意思就是当一个小时内层运行完一次之后,内层Timer释放资源,那么外层的Timer是不是也会释放,还是24小时之中一直都在占用?
不 太清楚此占用资源是什么意思,如果在Task中用到一些资源,这些资源应该在Task运行结束后即刻释放,尤其对竞态条件,更应该占用尽量少的时间。一般 来说,一次Task的运行时间,将少于你设定的周期。否则,Task将在Timer中堆积起来。如果要实现上面说的每24小时和每1小时两个周期的操作, 可以使用一个Timer,schedule两个Task即可。

5. Timer是否可以在多线程环境下使用?
可以。Timer中用于存储Task的容器是同步了的,保证了多线程环境先的安全使用。

6. 定时的时间能为变量,可以在程序中变化吗?就是说定时的时间可以又界面来控制。
一 个Timer可以控制任意多个Task的不同周期设定的触发。也就是说,这个Timer类似于可以定多个时间的闹钟,比如我的手机就有3个闹 钟 :)  。但是一旦一个Task 已经进行了schedule了,那么就不能再次进行设定。所以,也不可能再改变其周期、延迟等等设定了。可以看下面 的代码:

  1.             synchronized (task.lock) {
  2.                 if  (task.state != TimerTask .VIRGIN)
  3.                     throw  new  IllegalStateException (
  4.                         "Task already scheduled or cancelled" );
  5.                 task.nextExecutionTime = time;
  6.                 task.period = period;
  7.                 task.state = TimerTask .SCHEDULED;
  8.             }


7. 可不可以认为Timer就是一个线程的发射器?
Timer中仅有一个存储Task的Queue和一个调度所有Task的线程。不管你schedule几次,在Timer上加了几个Task,都只有一个后台的线程进行调度。

分享到:
评论

相关推荐

    JAVA_API1.6文档(中文)

    java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口。 java.awt.print 为通用的打印 API 提供类和接口。 java.beans 包含与开发 beans 有关的类,...

    JavaAPI中文chm文档 part2

    java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口。 java.awt.print 为通用的打印 API 提供类和接口。 java.beans 包含与开发 beans 有关的类,...

    Java 1.6 API 中文 New

    java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口。 java.awt.print 为通用的打印 API 提供类和接口。 java.beans 包含与开发 beans 有关的类,即...

    java api最新7.0

    java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口。 java.awt.print 为通用的打印 API 提供类和接口。 java.beans 包含与开发 beans 有关的类,即...

    [Java参考文档].JDK_API 1.6

    java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口。 java.awt.print 为通用的打印 API 提供类和接口。 java.beans 包含与开发 beans 有关的类,即...

    JavaAPI1.6中文chm文档 part1

    java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口。 java.awt.print 为通用的打印 API 提供类和接口。 java.beans 包含与开发 beans 有关的类,...

    [Java参考文档]

    java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口。 java.awt.print 为通用的打印 API 提供类和接口。 java.beans 包含与开发 beans 有关的类,...

    JDK_1_6 API

    java.awt.image 提供创建和修改图像的各种类。 java.awt.image.renderable 提供用于生成与呈现无关的图像的类和接口。 java.awt.print 为通用的打印 API 提供类和接口。 java.beans 包含与开发 beans 有关的类,即...

    java jdk实列宝典 光盘源代码

    java为数据结构中的列表定义了一个接口类java.util.list同时提供了3个实现类,分别是ArrayList、Vector、LinkedList使用; 生成不重复的随机数序列;列表、集合与数组的互相转换;java为数据结构中的映射定义一个接口...

    JAVA上百实例源码以及开源项目源代码

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java源码包---java 源码 大量 实例

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    JAVA上百实例源码以及开源项目

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    Java学习笔记-个人整理的

    {13.8}java.util.Date与java.sql.Date比较}{200}{section.13.8} {13.9}Meta Data}{201}{section.13.9} {13.10}可滚动结果集}{201}{section.13.10} {13.11}Procedure}{201}{section.13.11} {14}xml}{204}{...

    java源码包4

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java源码包3

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    java源码包2

     util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印图片的路径,水印一般格式是gif,png,这种图片可以设置透明度、水印旋转等,可以参考代码...

    成百上千个Java 源码DEMO 4(1-4是独立压缩包)

    Java数组倒置 简单 Java图片加水印,支持旋转和透明度设置 摘要:Java源码,文件操作,图片水印 util实现Java图片水印添加功能,有添加图片水印和文字水印,可以设置水印位置,透明度、设置对线段锯齿状边缘处理、水印...

Global site tag (gtag.js) - Google Analytics