4

我必须为以下场景实现一个简单的 Timer 任务 -

method1(){  
.....  
   if(success){  
      trigger method2 for next 30 min every 15 sec  
   }  
}

我已经使用 java.util.Timer 和 java.util.TimerTask 实现了这段代码,并且工作正常。但是,我的代码最终将部署为 glassfish 服务器中的 Web 服务。所以我想知道它是否会由于 glassfish 容器而产生任何问题,因为我通过 Timer 间接使用线程。

我也不确定是否应该使用 EJB Timer Bean。有人可以请教这两种方法的优缺点吗?

4

2 回答 2

5

EJB 规范警告用户编码(或第三方编码)线程。

企业 bean 不得尝试管理线程。企业 bean 不得尝试启动、停止、挂起或恢复线程,或者更改线程的优先级或名称。企业 bean 不得尝试管理线程组。21.2.2 编程限制,EJB 3.1 规范)

首选 EJB Timer Bean。

于 2013-01-22T04:48:26.680 回答
2

与大多数 EJB 一样,这两种技术之间的最大区别是事务。Timer EJB 就是 EJB,所以每次调用都是一个唯一的事务,容器将为您管理所有这些细节。

线程,尤其是从 EJB 中创建的线程,将具有未确定的事务状态。大多数容器将很多上下文与当前正在执行的线程相关联,尤其是事务状态,这是(其中之一)自制线程在 EJB 容器中是一个坏主意的原因之一——容器上下文信息可能会丢失或损坏。

对于 EJB 计时器,您可以轻松地创建一个每 15 秒触发一次的计时器,但您需要跟踪并在 30 分钟后手动取消它。您可以使用 ScheduleExpression 来表达“每 15s 30m”规则,但您仍然需要在最后取消计时器(坦率地说,正确创建该表达式会做更多的工作)。在 Timers Info 中添加一个开始时间会更容易,告诉它何时开始,然后它可以在最后一次运行时自行终止。

在 Java EE 6 之前的日子里,定时器是持久的,并且在容器重新启动时仍然存在(尽管不是应用程序重新部署)。现在,持久性是可选的,因此您需要注意该细节。

如果这个方法是从 Web 层(而不是 EJB 层)触发的,那么线程限制就会放宽,或者您可以使用 Quartz Timer。

但是 EJB 计时器非常好,并且更适合 Java EE 6。会使用 EJB 计时器,但我对它们很满意,并且已经使用了一段时间以来更难使用的 Java EE 6 之前的计时器。如果您在整个过程的 EJB 层中,我当然会使用它们。

于 2013-01-22T05:11:23.763 回答