`

JAVA中多种计时器的比较与分析

    博客分类:
  • J2SE
阅读更多

介绍 

计时器可以提供运行基于时间的工作任务的功能,在计时器的管理下,特定的任务可在某一时间运行一次,也可以按指定的时间间隔反复运行。在众多厂商提供的计时器中应用得比较多的有以下三种: 

● java.util.Timer 

Sun JDK 提供的一种轻量级的计时器。 
● Commonj Timer 

IBM 和 BEA 联合制定和推出的一种适用于 J2EE 环境的计时器。 
● WebSphere Application Server Scheduler 

IBM WebSphere Application Server 提供的一种功能强大的计时器。 


java.util.Timer 

java.util.Timer 是 Sun JDK 提供的一种计时器,用于使后台线程按计划执行指定任务,这些任务可以被执行一次,也可以被定期执行。每个 Timer 对象对应一个后台线程,顺序地执行所有计时器任务。如果完成某个计时器任务的时间太长,那么它会“独占”计时器的任务执行线程,从而可能延迟后续任务的执行。对 Timer 对象最后的引用完成并且所有未处理的任务都已执行完成后,计时器的任务执行线程会正常终止(并且成为垃圾回收的对象)。以下为一个使用 java.util.Timer 的例子: 

Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://huangtut.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=view%20plaincopy%20to%20clipboardprint%3F%0Aimport%20java.util.Timer%3B%20%20%20%0Aimport%20java.util.TimerTask%3B%20%20%20%0Apublic%20class%20TimerTest%20%7B%20%20%20%0A%20%20%20%20Timer%20timer%3B%20%20%20%0A%20%20%20%20public%20TimerTest(int%20seconds)%20%7B%20%20%20%0A%20%20%20%20%20%20%20%20timer%20%3D%20new%20Timer()%3B%20%20%20%0A%20%20%20%20%20%20%20%20timer.schedule(new%20TimerTestTask()%2C%20seconds*1000)%3B%20%20%20%0A%20%20%20%20%7D%20%20%20%0A%20%20%20%20class%20TimerTestTask%20extends%20TimerTask%20%7B%20%20%20%0A%20%20%20%20%20%20%20%20public%20void%20run()%20%7B%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(%22In%20TimerTestTask%2C%20execute%20run%20method.%22)%3B%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20timer.cancel()%3B%20%20%20%0A%20%20%20%20%20%20%20%20%7D%20%20%20%0A%20%20%20%20%7D%20%20%20%0A%20%20%20%20public%20static%20void%20main(String%20args%5B%5D)%20%7B%20%20%20%0A%20%20%20%20%20%20%20%20System.out.println(%22Prepare%20to%20schedule%20task.%22)%3B%20%20%20%0A%20%20%20%20%20%20%20%20new%20TimerTest(2)%3B%20%20%20%0A%20%20%20%20%20%20%20%20System.out.println(%22Task%20scheduled.%22)%3B%20%20%20%0A%20%20%20%20%7D%20%20%20%0A%7D%20%20%0Aimport%20java.util.Timer%3B%0Aimport%20java.util.TimerTask%3B%0Apublic%20class%20TimerTest%20%7B%0A%20%20%20%20Timer%20timer%3B%0A%20%20%20%20public%20TimerTest(int%20seconds)%20%7B%0A%20%20%20%20%20%20%20%20timer%20%3D%20new%20Timer()%3B%0A%20%20%20%20%20%20%20%20timer.schedule(new%20TimerTestTask()%2C%20seconds*1000)%3B%0A%20%20%20%20%7D%0A%20%20%20%20class%20TimerTestTask%20extends%20TimerTask%20%7B%0A%20%20%20%20%20%20%20%20public%20void%20run()%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(%22In%20TimerTestTask%2C%20execute%20run%20method.%22)%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20timer.cancel()%3B%20%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%7D%0A%20%20%20%20public%20static%20void%20main(String%20args%5B%5D)%20%7B%0A%20%20%20%20%20%20%20%20System.out.println(%22Prepare%20to%20schedule%20task.%22)%3B%0A%20%20%20%20%20%20%20%20new%20TimerTest(2)%3B%0A%20%20%20%20%20%20%20%20System.out.println(%22Task%20scheduled.%22)%3B%0A%20%20%20%20%7D%0A%7D%0A%20%0A"></embed>
  1. view plaincopy to clipboardprint?  
  2. import java.util.Timer;     
  3. import java.util.TimerTask;     
  4. public class TimerTest {     
  5.     Timer timer;     
  6.     public TimerTest(int seconds) {     
  7.         timer = new Timer();     
  8.         timer.schedule(new TimerTestTask(), seconds*1000);     
  9.     }     
  10.     class TimerTestTask extends TimerTask {     
  11.         public void run() {     
  12.             System.out.println("In TimerTestTask, execute run method.");     
  13.             timer.cancel();     
  14.         }     
  15.     }     
  16.     public static void main(String args[]) {     
  17.         System.out.println("Prepare to schedule task.");     
  18.         new TimerTest(2);     
  19.         System.out.println("Task scheduled.");     
  20.     }     
  21. }    
  22. import java.util.Timer;  
  23. import java.util.TimerTask;  
  24. public class TimerTest {  
  25.     Timer timer;  
  26.     public TimerTest(int seconds) {  
  27.         timer = new Timer();  
  28.         timer.schedule(new TimerTestTask(), seconds*1000);  
  29.     }  
  30.     class TimerTestTask extends TimerTask {  
  31.         public void run() {  
  32.             System.out.println("In TimerTestTask, execute run method.");  
  33.             timer.cancel();   
  34.         }  
  35.     }  
  36.     public static void main(String args[]) {  
  37.         System.out.println("Prepare to schedule task.");  
  38.         new TimerTest(2);  
  39.         System.out.println("Task scheduled.");  
  40.     }  
  41. }  
  42.    

java.util.Timer 简单易用,比较适合提供轻量级的计时器功能。由于其创建的线程会超出容器的管理范围,因此不能应用于管理的环境中。如果用户需要在 J2EE 环境中提供计时器功能,可考虑使用后面即将介绍的 Commonj Timer 或 WebSphere Application Server Scheduler。 



Commonj Timer 

Commonj Timer 是 Commonj 规范的一部分,它由 IBM 和 BEA 联合制定和推出,用以更好的响应客户和独立软件商的需求,给开发人员在开发可移植的服务端应用程序时提供一些更加简单和功能更加强大的方法。这个规范主要包括以下几个部分:Service Component Architecture,Service Data Objects,Work Manager and Timer 和 Enterprise Metadata Discovery。其中,Work Manager and Time 为在应用服务器中支持并发任务的执行提供了一些简单 API。这使用户可以方便地在 Servlet 和 EJB 中执行并发的计划任务,从而提高呑吐量,缩短服务端程序的响应时间,很好地解决了在 J2EE 环境中执行用户自定义的多线程并发与计时器服务的问题。 

Commonj Timer API 包括三个接口:TimerManager, Timer 和 TimerListener。应用程序可以通过 TimerManager 来定期调用 TimerListener。每个 TimerManager 的 shcedule 方法返回一个 Timer 对象。用户可以通过 TimerManager 的 JNDI 名称在管理环境的上下文中查找 TimerManager。 

用户可以通过以下三步来使用 Commonj Timer: 

1. 在 web.xml 或者 ejb-jar.xml 中增加 Timer 的描述: 
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://huangtut.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=view%20plaincopy%20to%20clipboardprint%3F%0A%3Cresource-ref%3E%20%20%20%0A%20%20%20%20%3Cres-ref-name%3Etimer%2FMyTimer%3C%2Fres-ref-name%3E%20%20%20%0A%20%20%20%20%3Cres-type%3Ecommonj.timer.TimerManager%3C%2Fres-type%3E%20%20%20%0A%20%20%20%20%3Cres-auth%3EContainer%3C%2Fres-auth%3E%20%20%20%0A%20%20%20%20%3Cres-sharing-scope%3EUnshareable%3C%2Fres-sharing-scope%3E%20%20%20%0A%3C%2Fresource-ref%3E%20%20%0A%20%20%20%20%20%20%3Cresource-ref%3E%0A%20%20%20%20%20%20%20%20%20%20%3Cres-ref-name%3Etimer%2FMyTimer%3C%2Fres-ref-name%3E%0A%20%20%20%20%20%20%20%20%20%20%3Cres-type%3Ecommonj.timer.TimerManager%3C%2Fres-type%3E%0A%20%20%20%20%20%20%20%20%20%20%3Cres-auth%3EContainer%3C%2Fres-auth%3E%0A%20%20%20%20%20%20%20%20%20%20%3Cres-sharing-scope%3EUnshareable%3C%2Fres-sharing-scope%3E%0A%20%20%20%20%20%20%3C%2Fresource-ref%3E%0A%20"></embed>
  1. view plaincopy to clipboardprint?  
  2. <resource-ref>     
  3.     <res-ref-name>timer/MyTimer</res-ref-name>     
  4.     <res-type>commonj.timer.TimerManager</res-type>     
  5.     <res-auth>Container</res-auth>     
  6.     <res-sharing-scope>Unshareable</res-sharing-scope>     
  7. </resource-ref>    
  8.       <resource-ref>  
  9.           <res-ref-name>timer/MyTimer</res-ref-name>  
  10.           <res-type>commonj.timer.TimerManager</res-type>  
  11.           <res-auth>Container</res-auth>  
  12.           <res-sharing-scope>Unshareable</res-sharing-scope>  
  13.       </resource-ref>  
  14.    




2. 实现 TimerListener 接口: 
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://huangtut.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=view%20plaincopy%20to%20clipboardprint%3F%0Aimport%20commonj.timers.Timer%3B%20%20%20%0Aimport%20commonj.timers.TimerListener%3B%20%20%20%0A%20%20%0Apublic%20class%20TestTimerListener%20implements%20TimerListener%20%7B%20%20%20%0A%20%20%20%20private%20String%20input%3B%20%20%20%0A%20%20%0A%20%20%20%20public%20TestTimerListener(String%20input)%20%7B%20%20%20%0A%20%20%20%20%20%20%20%20this.input%20%3D%20input%3B%20%20%20%0A%20%20%20%20%7D%20%20%20%0A%20%20%0A%20%20%20%20public%20void%20timerExpired(Timer%20timer)%20%7B%20%20%20%0A%20%20%20%20%20%20%20%20Date%20timeValue%20%3D%20new%20Date()%3B%20%20%20%0A%20%20%20%20%20%20%20%20System.out.println(%22In%20timerExpired%20method%2C%20time%20is%20%22%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%2B%20timeValue.toString()%20%2B%20%22%2C%20input%20value%20is%20%22%20%2B%20input)%3B%20%20%20%0A%20%20%20%20%7D%20%20%20%0A%7D%20%20%0A%20%20%20%20%20%20import%20commonj.timers.Timer%3B%0A%20%20%20%20%20%20import%20commonj.timers.TimerListener%3B%0A%0A%20%20%20%20%20%20public%20class%20TestTimerListener%20implements%20TimerListener%20%7B%0A%20%20%20%20%20%20%20%20%20%20private%20String%20input%3B%0A%0A%20%20%20%20%20%20%20%20%20%20public%20TestTimerListener(String%20input)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20this.input%20%3D%20input%3B%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%0A%20%20%20%20%20%20%20%20%20%20public%20void%20timerExpired(Timer%20timer)%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20Date%20timeValue%20%3D%20new%20Date()%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20System.out.println(%22In%20timerExpired%20method%2C%20time%20is%20%22%20%0A%20%20%20%20%20%20%09%09%20%20%20%20%2B%20timeValue.toString()%20%2B%20%22%2C%20input%20value%20is%20%22%20%2B%20input)%3B%0A%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%0A%0A"></embed>
  1. view plaincopy to clipboardprint?  
  2. import commonj.timers.Timer;     
  3. import commonj.timers.TimerListener;     
  4.     
  5. public class TestTimerListener implements TimerListener {     
  6.     private String input;     
  7.     
  8.     public TestTimerListener(String input) {     
  9.         this.input = input;     
  10.     }     
  11.     
  12.     public void timerExpired(Timer timer) {     
  13.         Date timeValue = new Date();     
  14.         System.out.println("In timerExpired method, time is "     
  15.             + timeValue.toString() + ", input value is " + input);     
  16.     }     
  17. }    
  18.       import commonj.timers.Timer;  
  19.       import commonj.timers.TimerListener;  
  20.   
  21.       public class TestTimerListener implements TimerListener {  
  22.           private String input;  
  23.   
  24.           public TestTimerListener(String input) {  
  25.               this.input = input;  
  26.           }  
  27.   
  28.           public void timerExpired(Timer timer) {  
  29.               Date timeValue = new Date();  
  30.               System.out.println("In timerExpired method, time is "   
  31.                 + timeValue.toString() + ", input value is " + input);  
  32.           }  
  33.       }  
  34.    

3. 查找 TimerManager,调用 TimerListener,初始化任务并设置时间: 
Java代码 <embed type="application/x-shockwave-flash" width="14" height="15" src="http://huangtut.iteye.com/javascripts/syntaxhighlighter/clipboard_new.swf" pluginspage="http://www.macromedia.com/go/getflashplayer" allowscriptaccess="always" quality="high" flashvars="clipboard=InitialContext%20ctx%20%3D%20new%20InitialContext()%3B%20%20%20%0ATimerManager%20mgr%20%3D%20(TimerManager)%20%20%20%0A%20%20%20%20ctx.lookup(%22java%3Acomp%2Fenv%2Ftimer%2FMyTimer%22)%3B%20%20%20%0ATimerListener%20listener%20%3Dnew%20TestTimerListener%20(%22test%22)%3B%20%20%20%0A%2F%2F%20%E5%90%AF%E5%8A%A8%E8%AE%A1%E6%97%B6%E5%99%A8%20%20%20%0Amgr.schedule(listener%2C%201000*60)%3B%20%20%20%0A%20%20%20%20%20%20InitialContext%20ctx%20%3D%20new%20InitialContext()%3B%0A%20%20%20%20%20%20TimerManager%20mgr%20%3D%20(TimerManager)%0A%20%20%20%20%20%20%09ctx.lookup(%22java%3Acomp%2Fenv%2Ftimer%2FMyTimer%22)%3B%0A%20%20%20%20%20%20TimerListener%20listener%20%3Dnew%20TestTimerListener%20(%22test%22)%3B%0A%20%20%20%20%20%20%2F%2F%20%E5%90%AF%E5%8A%A8%E8%AE%A1%E6%97%B6%E5%99%A8%0A%20%20%20%20%20%20mgr.schedule(listener%2C%201000*60)%3B%20%0A%20%0A"></embed>
  1. InitialContext ctx = new InitialContext();     
  2. TimerManager mgr = (TimerManager)     
  3.     ctx.lookup("java:comp/env/timer/MyTimer");     
  4. TimerListener listener =new TestTimerListener ("test");     
  5. // 启动计时器     
  6. mgr.schedule(listener, 1000*60);     
  7.       InitialContext ctx = new InitialContext();  
  8.       TimerManager mgr = (TimerManager)  
  9.         ctx.lookup("java:comp/env/timer/MyTimer");  
  10.       TimerListener listener =new TestTimerListener ("test");  
  11.       // 启动计时器  
  12.       mgr.schedule(listener, 1000*60);   
  13.    


Commonj Timer 提供了一种在 J2EE 环境中使用计时器的方法,它解决了 java.util.Timer 创建的线程超出容器管理范围的问题。由于它不同于 JMX Timer Service 与 JMX framework 之间的紧耦合,从而提供了更加友好和独立的 API。 Commonj Timer API 中的 timer 是瞬时的、非事务性的,并且运行于创建它的 JVM 中,因此对于对持久性、事务性和可恢复性有要求的集群环境并不适合。 



IBM WebSphere Application Server Scheduler 

IBM WebSphere Application Server Scheduler 是一种功能全面的定时器服务,提供了在 WebSphere Application Server 中配置、管理和开发基于时间的工作任务的功能,能够使 J2EE 操作具有高性能、持久性以及事务性等特征。Scheduler 具有以下优点: 

● 易于管理 

Scheduler 的创建、更新、调度、验证以及监控等任务是 WebSphere Application Server 中的管理控制台进行配置的,可在单个服务器、集群、节点或单元中创建 Scheduler。每个配置后的 Scheduler 拥有唯一的 JNDI 名称、持久存储设备和守护程序。 
图 1. WebSphere Application Server 管理控制台中的 Scheduler 配置面板  
 





● 具有持久性和事务健壮性 

Scheduler 任务可以通过存入关系数据库的方式被持久化,因此可以保证长期多次的运行。轮询守护程序使用这个数据库来确定哪些任务要运行以及什么时候运行。 
● 具有灵活的时间定制方式 

Scheduler 任务依据用户指定的日历在某一时间开始执行一次或多次任务,用户可根据需要订制自己的日历。 
● 具有扩展性 

当 Scheduler 服务运行于集群环境的时候,可以通过负载均衡管理提高性能和可用性。 


图 2. 集群环境
分享到:
评论
2 楼 yy8093 2015-08-02  
commonj 第三步,那个调用的方法要在哪里调?servlet?设置启动时自动加载?
1 楼 ErinToJerry 2010-12-14  
这篇文章很流传啊。~

相关推荐

    java写的计时器

    java写的计时器,可手动输入起始时间与终止时间,只有一个数,比较简单,多线程实现,适合初学者

    JAVA实现GUI计时器+贪吃蛇+扫雷

    上班闲着无聊做了一个JAVA版的GUI计时器,包括了中午的打卡时间、下午的下班时间、周末的倒计时和当天已加班的时间。后续又整合了国内各个能放假的节日倒计时(包括春节、中秋等农历节日)。最后 实在是闲着没事 做...

    java倒计时器代码

    java倒计时器代码,主要是怎样利用java来编写倒计时器的代码。欢迎下载和分享!

    java可视化计时器

    一个java 计时窗口的代码例子 一个java 计时窗口的代码例子 一个java 计时窗口的代码例子

    倒计时器 java

    java写的倒计时小程序,包含一个JAR文件双击可运行,供初写JAVA者学习

    用java编写的计时器

    用java编写的计时器,非常简单额,……

    java swing计时器

    这是一个倒计时器的工程,下边的jar文件是打包好的程序,可以使用,也可以自行修改程序。 30秒字体变红。 支持计时前准备时间。

    java 计时器

    java 计时器用法 GregorianCalendar用法

    java弄的计时器

    一个小计时器,用来进行计时的,简单的java写的

    java 秒表计时器

    秒表类(MyStopWatch) 功能: 1.启动计时器 2.停止计时器 3.暂停计时 4.恢复被暂停的秒表 5.分段计时

    java计时器设置定时任务

    java计时器,设置定时任务,执行该任务

    JAVA倒计时器

    一个简单界面的JAVA倒计时器,适合新手学习,代码简单

    JAVA倒计时器练习程序

    JAVA写的简单的倒计时器,可以多组倒计时

    使用java编写的小型计时器

    使用java编写的小型计时器,可以用来计算当月上网时间,能最小化到托盘,并且有倒计时功能,时间一到可自动弹出等。

    Java计时器[文].pdf

    Java计时器[文].pdf

    java电脑开机计时器

    将Timer.jar放入 开始-&gt;所有程序-&gt;启动 这个文件夹中 当你下次开机时它将自动启动从而开始计时 在C:\TimeLog文件夹下就可以看到记录日志

    一个java计时器,具有一般的计时功能

    这事一个用java编写的计时器,具有一般的时钟功能,但还是过于简陋,希望您看过后加以完善

    java计时器经典例子

    精典小例:程序的任务是:使用计时器使程序从开始运行后每隔3秒在控制台打印出系统当前时间,配有源码

    Java计时器

    一个简易的Java计时器,可以试着去做一做

Global site tag (gtag.js) - Google Analytics