有许多方法可以做到这一点。
一种方法是使用EJB定时器来创建一个立即启动的单次运行过程。这是一种在后台生成进程的好技术。EJB定时器与特定的Session Bean实现关联。您可以将EJB定时器添加到每个要执行此操作的Session Bean中,或者您可以拥有一个单独的Session Bean,然后通过某些调度机制调用您的应用逻辑。
对于我而言,我会传递一个可序列化的参数块和一个符合特定接口的类名,然后将其发送到通用Session Bean中,该Bean随后执行该类。这样我就可以轻松地后台处理大部分事情。
EJB定时器的一个注意点是EJB定时器是持久的。一旦您创建了一个EJB定时器,它会一直保留在容器中,直到其工作完成或被取消为止。其中一个问题是,如果您有一个长时间运行的进程,并且服务器关闭,当它重新启动时,进程将继续并继续进行。这可能是件好事,但前提是您的进程准备好重新启动。但如果您只是简单地遍历"10,000个项目"的过程,在服务器在第9999个项目处停止运行时,当它重新启动时,很可能会从项目1重新开始。这都是可以解决的,只是要注意一下。
另一种后台处理的方法是使用JMS队列。将消息放入队列中,然后处理程序从您的应用程序的其余部分异步运行。
聪明之处在于,也利用定时器Bean的工作,您可以根据配置系统拥有的MDB实例数量控制将有多少个"作业"运行。
因此,对于以多个并行块运行进程的特定任务,我接收任务,将其拆分成"片段",然后将每个片段发送到消息队列中,在那里MDB将执行它们。如果允许10个MDB实例,则可以同时运行任何任务的10个"部分"。
这种方式出奇的好用。将进程分解并通过JMS队列路由存在一定的额外开销,但基本上都是"启动时间"。一旦开始运行,你就会获得真正的好处。
使用消息队列的另一个好处是,你可以在单独的机器上执行实际的长时间运行的进程,或者你可以轻松创建一组机器来处理这些进程。然而,接口是相同的,代码并不知道区别。
我发现,一旦将长时间运行的进程调入后台,你可以付出价格,即访问该进程时没有立即响应。也就是说,没有理由直接监视执行类本身,只需让它们发布有趣的信息和统计数据到数据库、JMX或其他地方,而不是像共享同一内存空间的对象那样直接监视对象本身。
我很容易设置一个框架,让任务在EJB Timer或MDB散列队列上运行,任务是相同的,我可以监视它们的进度,停止它们等等。
你可以将散列技术与EJB Timer作业结合起来创建几个作业。 MDB的一个免费好处是它充当线程池,可以调整作业的速度(以避免突然饱和系统过多的后台进程)。通过利用容器中的EJB管理功能,你可以免费获得这个优势。
最后,Java EE6有一个新的"异步"(或其他)修饰符用于会话Bean方法。我不知道它是如何工作的细节,因为我还没有尝试过新的Java EE6容器。但我想你可能不想仅仅为了使用这个设施而更换容器。
WorkManager
是WebSphere专用的,因此通常不适用:https://dev59.com/QV_Va4cB1Zd3GeqPWb0l - Raedwald