有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

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

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

ManagedExecutorService是否适用于此


共 (3) 个答案

  1. # 1 楼答案

    ManagedExecutorService正是您想要使用的

    JEE提供这项服务是一个巨大的好处。过去,我们基本上只是忽略了指导方针,自己管理所有这些东西

    MES允许您捕获调用组件的上下文信息,并将任务与容器的生命周期联系起来。这两者在JEE环境中都非常重要

    至于从哪里开始这项任务,你基本上有两个选择

    首先,您可以使用ServletContextListener,并在容器启动期间启动该任务

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

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

    不管怎样,你只需要担心通过这些机制启动任务。你应该依靠ManagedTaskListener。taskAborted接口方法关闭任务

    理论上,你可以使用线程。在关机期间发送给任务的中断。我自己从来没有这么幸运过,我依靠一个外部机制来告诉长期运行的任务关闭

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

  2. # 2 楼答案

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

  3. # 3 楼答案

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

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