`

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

    博客分类:
  • Java
阅读更多
介绍

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

● 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 的例子:
view plaincopy to clipboardprint?
import java.util.Timer;   
import java.util.TimerTask;   
public class TimerTest {   
    Timer timer;   
    public TimerTest(int seconds) {   
        timer = new Timer();   
        timer.schedule(new TimerTestTask(), seconds*1000);   
    }   
    class TimerTestTask extends TimerTask {   
        public void run() {   
            System.out.println("In TimerTestTask, execute run method.");   
            timer.cancel();   
        }   
    }   
    public static void main(String args[]) {   
        System.out.println("Prepare to schedule task.");   
        new TimerTest(2);   
        System.out.println("Task scheduled.");   
    }   
}  
import java.util.Timer;
import java.util.TimerTask;
public class TimerTest {
    Timer timer;
    public TimerTest(int seconds) {
        timer = new Timer();
        timer.schedule(new TimerTestTask(), seconds*1000);
    }
    class TimerTestTask extends TimerTask {
        public void run() {
            System.out.println("In TimerTestTask, execute run method.");
            timer.cancel(); 
        }
    }
    public static void main(String args[]) {
        System.out.println("Prepare to schedule task.");
        new TimerTest(2);
        System.out.println("Task scheduled.");
    }
}
 

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 的描述:
view plaincopy to clipboardprint?
<resource-ref>   
    <res-ref-name>timer/MyTimer</res-ref-name>   
    <res-type>commonj.timer.TimerManager</res-type>   
    <res-auth>Container</res-auth>   
    <res-sharing-scope>Unshareable</res-sharing-scope>   
</resource-ref>  
      <resource-ref>
          <res-ref-name>timer/MyTimer</res-ref-name>
          <res-type>commonj.timer.TimerManager</res-type>
          <res-auth>Container</res-auth>
          <res-sharing-scope>Unshareable</res-sharing-scope>
      </resource-ref>
 




2. 实现 TimerListener 接口:
view plaincopy to clipboardprint?
import commonj.timers.Timer;   
import commonj.timers.TimerListener;   
  
public class TestTimerListener implements TimerListener {   
    private String input;   
  
    public TestTimerListener(String input) {   
        this.input = input;   
    }   
  
    public void timerExpired(Timer timer) {   
        Date timeValue = new Date();   
        System.out.println("In timerExpired method, time is "   
            + timeValue.toString() + ", input value is " + input);   
    }   
}  
      import commonj.timers.Timer;
      import commonj.timers.TimerListener;

      public class TestTimerListener implements TimerListener {
          private String input;

          public TestTimerListener(String input) {
              this.input = input;
          }

          public void timerExpired(Timer timer) {
              Date timeValue = new Date();
              System.out.println("In timerExpired method, time is " 
      		    + timeValue.toString() + ", input value is " + input);
          }
      }
 


3. 查找 TimerManager,调用 TimerListener,初始化任务并设置时间:
InitialContext ctx = new InitialContext();   
TimerManager mgr = (TimerManager)   
    ctx.lookup("java:comp/env/timer/MyTimer");   
TimerListener listener =new TestTimerListener ("test");   
// 启动计时器   
mgr.schedule(listener, 1000*60);   
      InitialContext ctx = new InitialContext();
      TimerManager mgr = (TimerManager)
      	ctx.lookup("java:comp/env/timer/MyTimer");
      TimerListener listener =new TestTimerListener ("test");
      // 启动计时器
      mgr.schedule(listener, 1000*60); 
 


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. 集群环境中的 Scheduler



使用 WebSphere Application Server Scheduler 服务可通过以下三个步骤:

● 在 WebSphere Application Server 管理控制台配置 Scheduler 服务;
● 开发调用 Scheduler 服务代码;
● 部署;

Scheduler 服务可由以下两种方式调用:调用会话 Bean 的任务,发送 Java 消息的服务。本文中使用调用会话 Bean 的任务说明如何调用 Scheduler 服务。

1. 创建一个 EJB 项目用以开发由会话 Bean 实现的任务,在 EJB Module 中创建一个无状态 Session Bean(ScheduledTask),在部署描述符中添加 com.ibm.websphere.scheduler.TaskHandlerHome 和 com.ibm.websphere.scheduler.TaskHandler 作为远程 Home 接口和远程接口。
2. 实现 ScheduledTask 的 process 方法。
  
public void process(TaskStatus status) {   
    Date timeValue = new Date();   
    System.out.println("In process method, time is " + timeValue.toString());   
}   
…  
      …
      public void process(TaskStatus status) {
          Date timeValue = new Date();
          System.out.println("In process method, time is " + timeValue.toString());
      }
      …
 

3. 在需要调用 Scheduler 服务的方法中查找 Scheduler,创建 BeanTaskInfo 实例并启动 scheduler。
view plaincopy to clipboardprint?
// 在J2EE上下文环境中查找scheduler   
Scheduler scheduler = (Scheduler)   
new InitialContext.lookup("java:comp/env/sched/MyTestScheduler");   
Object o = ctx.lookup("ejb/com/test/ScheduledTask");   
TaskHandlerHome home =   
  (TaskHandlerHome)javax.rmi.PortableRemoteObject.narrow(o, TaskHandlerHome.class);   
  
// 设置任务启动时间   
java.util.Date startDate = new java.util.Date(System.currentTimeMillis()+3000);   
  
// 设置BeanTaskInfo   
BeanTaskInfo taskInfo = (BeanTaskInfo) scheduler.createTaskInfo(BeanTaskInfo.class);   
taskInfo.setName("testTask");   
taskInfo.setTaskHandler(home);   
taskInfo.setStartTime(startDate);   
taskInfo.setRepeatInterval("600seconds");   
taskInfo.setNumberOfRepeats(-1); //重复直至任务被取消   
taskInfo.setQOS(BeanTaskInfo.QOS_ATLEASTONCE);   
       
// 启动scheduler和任务   
TaskStatus status = scheduler.create(taskInfo);   
      // 在J2EE上下文环境中查找scheduler
      Scheduler scheduler = (Scheduler)
      new InitialContext.lookup("java:comp/env/sched/MyTestScheduler");
      Object o = ctx.lookup("ejb/com/test/ScheduledTask");
      TaskHandlerHome home = 
        (TaskHandlerHome)javax.rmi.PortableRemoteObject.narrow(o, TaskHandlerHome.class);

      // 设置任务启动时间
      java.util.Date startDate = new java.util.Date(System.currentTimeMillis()+3000);

      // 设置BeanTaskInfo
      BeanTaskInfo taskInfo = (BeanTaskInfo) scheduler.createTaskInfo(BeanTaskInfo.class);
      taskInfo.setName("testTask");
      taskInfo.setTaskHandler(home);
      taskInfo.setStartTime(startDate);
      taskInfo.setRepeatInterval("600seconds");
      taskInfo.setNumberOfRepeats(-1); //重复直至任务被取消
      taskInfo.setQOS(BeanTaskInfo.QOS_ATLEASTONCE);
          
      // 启动scheduler和任务
      TaskStatus status = scheduler.create(taskInfo); 
 



WebSphere Application Server Scheduler 易于管理,具有持久性和事务性,可扩展,可应用于集群环境,为 J2EE 应用提供了功能全面的计时器服务,但由于它与 WebSphere Application Server 的紧耦合关系,降低了它的灵活性,造成了一定的局限。


总结

java.util.Timer、 CommonJ Timer 和 WebSphere Application Server Scheduler 为用户提供了不同级别的、适用与不同范围的计时器,用户可以根据各自的需求使用不同的计时器,表 1 列出了 java.util.Timer、Commonj Timer 和 WebSphere Application Server Scheduler 之间比较结果,用户在使用计时器时可以用来参照比较。

表 1. 计时器比较结果
java.util.Timer
来源:Sun
优点:易于使用轻量级
缺点:创建的线程会超出容器管理范围
适用范围:非 J2EE 环境

Commonj Timer
来源:BEA and IBM
优点:解决了 java.util.Timer 创建的线程超出容器管理范围的问题;不同于 JMX Timer Service 与 JMX framework 之间的紧耦合,提供了更加友好和独立的 API
缺点:timer 是瞬时的、非事务性的,并且运行于创建它的 JVM 中,不适合于集群环境
适用范围:J2EE 普通环境

java.util.Timer
来源:WebSphere Application Server Scheduler
优点:易于管理 具有持久性和事务性 具有灵活的时间定制方式 具有扩展性,适用于集群环境
缺点:与 WebSphere Application Server 紧耦合
适用范围:J2EE 普通和集群环境
  • 大小: 29.6 KB
  • 大小: 115 KB
分享到:
评论

相关推荐

    用java编写的计时器

    以上介绍了三种在Java中实现计时器的方法。选择哪种方法取决于具体的使用场景: - 如果对精度要求不高,追求简洁易懂的实现,可以选择使用`java.util.Date`的方式。 - 如果需要更高的效率和一定的精度,推荐使用`...

    计时器倒计时器裁判员专用

    2. **事件循环与定时器**:在程序中,计时器功能通常是通过定时器(Timer)类来实现的。例如,JavaScript中的`setInterval`函数或`setTimeout`函数,或是.NET框架中的`System.Windows.Forms.Timer`类。这些定时器会...

    GUI中用线程实现倒计时

    在图形用户界面(GUI)开发中,实现倒计时功能是非常常见的需求之一,尤其是在计时器应用、在线考试系统、游戏等领域。Java作为一种广泛使用的编程语言,提供了强大的Swing库来构建丰富的GUI应用程序。通过结合Swing...

    通话计时器

    【通话计时器】是一款专...综上所述,【通话计时器】这款应用融合了多种Android开发技术和实践,旨在提供便捷、全面的通话记录和统计服务,同时也展示了Android开发者在功能实现、用户体验优化和数据处理上的综合能力。

    简单的实现桌面小闹钟,和计时器功能。

    综上所述,实现一个桌面小闹钟和计时器功能涵盖了多种IT技术,包括时间处理、GUI设计、事件驱动编程、多线程、数据持久化、错误处理以及调试。这个过程既锻炼了编程技巧,也提升了对整个软件开发流程的理解。尽管...

    扫雷JAVA实现源码

    5. **多线程**:为了实现游戏的实时更新,比如计时器功能,可能需要用到JAVA的Thread或者Runnable接口,实现并发执行。 6. **错误处理**:在编写扫雷游戏时,必须考虑错误情况,如非法点击、游戏结束等,这需要使用...

    JAVA 拼图游戏 可选图,可选难度,游戏计时

    JAVA Swing提供了多种布局管理器,如FlowLayout、BorderLayout、GridLayout等,用于控制组件在窗口中的位置和大小。开发者可能会根据拼图的特性和需求选择合适的布局管理器,比如GridLayout可以方便地将拼图块均匀...

    Java程序监控API Java Simon

    Java Simon 是一个强大的Java应用程序监控API,它提供了一组丰富的计时器、计数器、内存计数器和采样器等工具,帮助开发者实时监控和优化应用性能。这个库小巧且易于集成,使得开发者可以在开发阶段就对代码进行性能...

    java程序_秒表

    为了增强秒表的功能,可以考虑添加计时器任务、多线程支持、或者与日志框架集成,以便记录性能数据。例如,可以在`stop()`方法中添加逻辑,将结果打印到控制台或写入日志文件。 ```java public void stopAndLog...

    java连连看游戏源码程序

    1. **面向对象编程**:Java是一种面向对象的语言,游戏中的每个元素(如棋盘、图标、计时器等)都可以被抽象为类,每个类都有其特定的属性和行为。例如,可以有一个`GameBoard`类来表示游戏棋盘,`Pair`类来表示可以...

    java统计方法执行时长

    在Java编程语言中,统计方法执行时长是一个常见的性能分析任务,它可以帮助开发者优化代码...无论是简单的计时器,还是利用JVM提供的管理接口,甚至是采用AOP进行自动化监控,都能帮助我们更好地理解和优化代码的性能。

    基于JAVA做的连连看程序

    - 类与对象:游戏中的每个元素,如方块、计时器、用户界面等,都可以抽象为类,通过对象实例化来创建游戏场景。 - 继承与多态:游戏可能有多种类型的方块,它们可能共享一些基本属性,可以使用继承来减少代码重复。...

    java小时钟源码

    Java小时钟源码是一个非常适合初学者和有一定编程基础的开发者学习的项目,它展示了如何使用Java...通过研究和修改这个小时钟代码,你可以进一步提高自己的编程技能,甚至可以尝试添加更多的功能,如闹钟、计时器等。

    打字测试软件(JAVA)

    1. **输入检测**:软件需要实时监测用户的键盘输入,与预设的文本进行比较,判断是否正确,并记录错误次数。 2. **计时器**:为测试设置时间限制,模拟实际的打字速度测试环境,增加挑战性。 3. **成绩计算**:根据...

    java版坦克大战源码

    - **帧率控制**:为了保持游戏流畅,通常会设定每秒的帧数(FPS),并通过计时器控制每一帧的执行时间。 4. **图形绘制** - **Java的Graphics类**:用于在屏幕上绘制图像,包括坦克、子弹、地图等。源码中会看到...

    用Java实现的音乐播放器

    这可能需要额外的计时器或者线程来跟踪和更新播放状态,并提供相应的设置选项。 总的来说,这个Java音乐播放器项目涵盖了多方面的Java编程技术,包括多媒体处理、事件驱动编程、GUI设计以及文件I/O操作。通过这个...

    JAVA程序包

    开发者可以利用这些工具构建游戏界面,比如设置按钮、文本框、计时器等元素,增强游戏的交互性。 5. **网络编程**:Java的Socket编程接口使得创建网络连接和数据交换变得简单,这对于开发多人在线游戏尤其有用。...

    Java获得系统时间

    // 定义了一个计时器对象,但未在示例中使用。 Calendar c = Calendar.getInstance(); // 获取当前日历实例。 Date date = c.getTime(); // 通过日历实例获取当前日期时间。 // Date date = new Date(); // 另一...

    Java连连看游戏程序源码

    【Java连连看游戏程序源码】是一个基于Java编程语言实现的桌面游戏,它利用了Java的GUI(图形用户界面)...通过分析和学习这个游戏的源码,不仅可以熟悉Java Swing的使用,还能掌握到实际项目中的算法设计和实现技巧。

    《java并发编程实践》

    2. **同步机制**:Java提供了多种同步工具,如synchronized关键字、Lock接口(包括ReentrantLock可重入锁)、Semaphore信号量、CountDownLatch倒计时器等。理解它们的工作原理和使用场景至关重要,因为这能防止数据...

Global site tag (gtag.js) - Google Analytics