【问题标题】:How to start a background process in Java EE如何在 Java EE 中启动后台进程
【发布时间】:2009-06-25 20:42:51
【问题描述】:

我想在 Java EE (OC4J 10) 环境中启动后台进程。只用“新线程”开始一个线程似乎是错误的,但我找不到一个好的方法。

在我的特殊情况下,使用 JMS 队列很困难,因为我用于此方法调用的参数不可序列化。

我还考虑过在会话 bean 上使用 onTimeout Timer 方法,但这不允许我传递参数(据我所知)。

是否有任何“经典”方式来处理这样的任务,或者我只需要恢复到“新线程”或java.concurrent.ThreadPool

【问题讨论】:

    标签: java jakarta-ee ejb


    【解决方案1】:

    Java EE 通常会尝试从开发人员的关注中移除线程。 (这是一个完全不同的话题)。

    JMS 显然是处理此问题的首选方法。

    对于大多数参数,您可以选择强制或伪造序列化,即使默认情况下它们不可序列化。根据数据,考虑将其包装在可以重新加载数据的可序列化对象中。这显然取决于参数和应用。

    【讨论】:

    • 我不太喜欢它,但我想我会那样做。谢谢
    • @ptriller 根据具体情况,WorkManager 是首选方法。它为许多应用服务器实现,并允许创建托管线程。 stackoverflow.com/questions/533783/…
    【解决方案2】:

    JMS 是执行此操作的 Java EE 方式。如果容器允许,您可以启动自己的线程,但这确实违反了 Java EE 规范(您可能关心也可能不关心)。

    如果您不关心 Java EE 通用合规性(如果您实际上会求助于线程而不是处理 JMS),那么 Oracle 容器肯定会有专有的方法来做到这一点(例如 OracleAS Job Scheduler) .

    【讨论】:

      【解决方案3】:

      不详细了解 OCJ4,但我使用 Thread 方法和 java.util.Timer 方法在基于 Tomcat 的应用程序中执行某些任务。在 Java 5+ 中,可以选择使用其中一种 Executor 服务(Sheduled、Priority)。

      我不知道 onTimeout 但您可以在会话本身、应用程序上下文或静态变量中传递参数(有人会说不鼓励)。但是这个名字告诉我当用户的会话超时并且你想要做一些清理时调用它。

      【讨论】:

      • 我认为 OP 知道这一切,他们在询问 JavaEE 是否提供了官方的方式来做到这一点。 JavaEE 容器有权禁止创建应用程序级线程,但它并没有真正提供可行的替代方案。
      • 当然是 OP。只是想列出问题中未列出的一些替代方案。
      • 如果您想对 JMS 进行类比,请使用 URLConnection 向您自己的 servlet 发出 HTTP 请求,该 servlet 具有您需要执行的操作。丑吗?
      【解决方案4】:

      使用 JMS 是正确的做法,但它的重量更大。

      您获得的好处是,如果您需要多台服务器、一台服务器或其他任何服务器,一旦配置了服务器,您的“线程”现在可以分布到多台机器上。

      这也意味着您不想为真正微不足道的工作量或大量数据发送消息。选择好你的接口点。

      【讨论】:

        【解决方案5】:

        请参阅此处了解更多信息: stackoverflow.com/questions/533783/why-spawning-threads-in-j2ee-container-is-discouraged

        我一直在容器(Tomcat、JBoss)中创建线程没有问题,但它们是非常简单的队列,我不依赖集群。

        但是,EJB 3.1 将引入您可能会发现有用的异步调用: http://www.theserverside.com/tt/articles/article.tss?track=NL-461&ad=700869&l=EJB3-1Maturity&asrc=EM_NLN_6665442&uid=2882457

        【讨论】:

          【解决方案6】:

          Java EE 并没有真正禁止您创建自己的线程,它是 EJB 规范规定不允许“非托管线程”。原因是应用服务器不知道这些线程,因此容器无法管理这些线程上的安全性和事务等事情。

          尽管如此,仍有许多框架可以创建自己的线程。例如石英、轴和弹簧。更改是您已经使用其中之一,因此只要您知道后果,创建自己的线程并没有那么糟糕。也就是说,我同意其他人的观点,即使用 JMS 或 JCA 优于手动创建线程。

          顺便说一句,OC4J 允许您创建自己的线程。但是,它不允许从这些非托管线程进行 JNDI 查找。您可以通过指定 -userThreads 参数来禁用此限制。

          【讨论】:

          • 我很清楚这一点。如果我在 tomcat 或 jetty 中部署 ma webapp,我不太在意,但如果我使用完整的 j2ee 容器,我会尝试遵守标准,所以我也会非常仔细地查看我使用的框架。 Atually这个问题的根本原因是我试图使用spring-batch而不启动它自己的线程。如果我有替代方案,这是完全可以配置的。
          【解决方案7】:

          我来自 .NET 背景,JMS 对我来说似乎很重要。相反,我推荐Quartz,它是一个用于 Java 和 JEE 应用程序的后台调度库。 (我在我的 ASP.NET MVC 应用程序中使用 Quartz.NET 取得了很大的成功。)

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-11-14
            • 2011-08-03
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-05-04
            相关资源
            最近更新 更多