JEE7:创建永不退出的另一个线程的最佳方法

时间:2014-05-15 02:32:42

标签: java multithreading java-ee glassfish

我正在编写一个JEE7 / Glassfish 4应用程序,它从外部队列(RabbitMQ)读取数据并对其进行处理。它需要一个方法(我想是一个EJB方法),它包含一个永不退出的循环来读取队列。我想因为这个循环永远不会退出,所以它需要在一个单独的线程上。我的问题是,在JEE7应用程序中执行此操作的正确方法是什么?

这可能很明显,但ReadQueue()方法需要在应用启动时自动启动,并且必须永久运行。

ManagedExecutorService适用于此吗?

3 个答案:

答案 0 :(得分:1)

启动具有无限循环的线程,定期轮询队列通常不是一个好主意。队列的性质表明异步,事件驱动的处理。对于JEE世界中的此类问题,您有MDBs。这里唯一的问题是MDB需要JMS队列提供程序,但RabbitMQ使用不同的协议(AMQP)。您需要一个JMS-AMQP桥来完成这项工作。可能是Qpid JMS但不保证它会起作用。

答案 1 :(得分:0)

ManagedExecutorService正是您想要用于此目的的。

这项服务在JEE中的可用性是一个很大的好处。在过去,我们基本上只是忽略了这些指导方针并自己管理了所有这些内容。

MES允许您捕获调用组件的上下文信息,并将您的任务绑定到容器的生命周期。这些在JEE环境中都非常重要。

至于在哪里开始任务,你基本上有两个选择。

一,您可以使用ServletContextListener,并在容器启动期间启动任务。

其二,您可以使用@Singleton EJB,并使用其生命周期方法来启动任务。

如果从ServletContextListener启动任务,那么任务将像在WAR环境中一样运行。如果从@Singleton启动它,它将在Session Beans环境中运行(这主要与JNDI的显示方式有关)。

无论哪种方式,您只需要担心通过这些机制启动任务。您应该依赖ManagedTaskListener.taskAborted接口方法来关闭任务。

理论上,您可以使用在关闭期间发送到您的任务的Thread.interrupt。我自己从来没有好运,我依靠外部机制来告诉长时间运行的任务被关闭。

我希望我可以亲身体验这个新设施,但我还没有机会尝试一下。但是根据规范,这就是你想要做的。

答案 2 :(得分:-1)

以下是创建永不退出的线程的一种方法:

public class HelloRunnable implements Runnable {
    public void run() {
        while (true) {
            // do ReadQueue() here
        }
    }
    public static void main(String args[]) {
        (new Thread(new HelloRunnable())).start();
    }
}