Java 为什么EJB计时器服务使用单例作为标准?

Java 为什么EJB计时器服务使用单例作为标准?,java,timer,singleton,ejb,stateless,Java,Timer,Singleton,Ejb,Stateless,我最近一直在研究ejb,我也在阅读计时器服务,但即使我读过无状态、有状态和单实例类型的会话bean,我仍然很难弄清楚是什么使计时器服务具有多实例属性 我已经看到了一些例子,即使是最简单的例子也使用单例会话Bean,因此,如果我要编写一个简单的程序来测试它,使用无状态Bean可以吗,还是建议使用单例会话Bean?另外,如果可能的话,我能举一个无状态不是最优的例子吗?它使用单例的原因至少有两个: 一, 只有单例具有启动初始化功能。这意味着您可以在应用程序启动时注册计时器服务 二, 如果要使用无状态b

我最近一直在研究ejb,我也在阅读计时器服务,但即使我读过无状态、有状态和单实例类型的会话bean,我仍然很难弄清楚是什么使计时器服务具有多实例属性


我已经看到了一些例子,即使是最简单的例子也使用单例会话Bean,因此,如果我要编写一个简单的程序来测试它,使用无状态Bean可以吗,还是建议使用单例会话Bean?另外,如果可能的话,我能举一个无状态不是最优的例子吗?

它使用单例的原因至少有两个:

一,

只有单例具有启动初始化功能。这意味着您可以在应用程序启动时注册计时器服务

二,

如果要使用无状态bean,那么将在每个无状态bean设置中注册一个新的计时器服务来服务请求。singleton保证只注册一种计时器。想象一下,如果您无意中在无状态bean中使用了计时器,并且或多或少在同一时间创建了多个计时器来服务请求,那么会出现争用、完整性问题或金钱损失


如果要确保在同一基础bean实例上调用所有超时回调,请使用单例。如果您希望维护bean实例本身的状态,并且希望确保一次只能调用一个超时回调,那么这一点很重要(默认情况下,超时回调将使用singleton的并发管理设置,默认情况下,该设置是使用写锁进行容器管理的,因此一次只能调用singleton上的一个方法)

如果希望同时调用多个超时回调,请使用无状态回调。如果同时发生多个超时回调,EJB容器将创建新的bean实例

如果您想配置一个非持久性计时器,使其在应用程序开始运行时开始运行,那么您可以在无状态bean或单例bean上使用@Schedule注释,也可以使用带有@PostConstruct的@singleton@startupbean(如果需要无状态行为,可以将无状态bean注入无状态bean,并在启动期间调用无状态会话bean上的createTimer)