在Java EE容器中进行并发编程

4
我有几个使用了大量IO操作并且可以轻松分解成多个任务的Quartz定时作业。
这些作业是在Tomcat Web容器中由Spring实例化和调度的。
如果我在Job类中和Java EE容器内部使用java.util.concurrent API,这样做是否合适?
我是否能够通过使用FixedThreadPool来共享逻辑处理器(例如在此示例中使用两个核心)?
int numberOfCores = Runtime.getRuntime().availableProcessors();
final int poolSize = numberOfCores - 2 // Give away Two slots for TOMCAT
final ExecutorService executorPool = Executors.newFixedThreadPool(poolSize);
2个回答

1

是的,你可以这样做。

但在将你的工作放入Tomcat之前,请注意以下事项:

你是否在Tomcat中拥有一个Web应用程序?如果是,你的Web应用程序是否是高活跃度和高负载门户?
如果是,你的线程作业将占用Tomcat服务器宝贵的处理能力。

线程作业完成的工作是否与Tomcat紧密耦合或需要Tomcat?
如果你的作业确实是独立的,那么最好创建一个单独的批处理服务器并使用它。你可以查看Spring Batch的实现。


这个项目中没有高负载的Web应用程序,只有几个页面用于下载WebStart富客户端。这主要是一个后端服务器,通过RMI导出Spring服务。由于性能原因(与服务相同的Spring应用程序上下文),作业非常适合在服务器内部执行。 - webpat

1

也许要小心谨慎。

请注意,除了原始线程(我们称之为Web应用程序线程)外,没有其他线程能够可靠地与容器进行交互。通常情况下,在Java EE运行时中使用线程是不被鼓励的。但这并非没有先例。

Tomcat选项:

  1. Java EE有一个WorkManager API。至少有一个适用于tomcat的实现。我无法确定它的工作效果如何。这篇文章讨论了更多细节

  2. 启动你自己的线程。可以借鉴 Swing Event Dispatch Loop 的模型和 SwingUtilities.invokeLater(Runnable); 在你的情况下,将工作提交给容器,在容器安全的Web应用程序线程中处理工作。该线程将运行一个hand-work循环同时等待worker-threads完成。

  3. 将worker请求发送回到tomcat服务器:你的Web应用程序现在充当客户端(Web服务?)。这种模型可以很好地扩展以卸载工作,就像AkhilDev建议的那样,将任务卸载到其他服务器上。


好的比喻!我该如何掌握“Web 应用程序线程”?J2EE 规范允许这种操作吗? - webpat
@Webpat,你的代码运行在一个线程上,对吗?Thread.currentThread(),这是Java EE容器支持的唯一线程。 - Richard Sitze
@Webpat,你的代码正在一个线程上运行,对吧?Thread.currentThread()。这是Java EE容器支持的唯一线程。使用线程是全部开箱即用的。由于你正在使用Tomcat,它是Java EE的子集,所以这并不(也许)那么不合理。答案已更新,并提供了其他选项。 - Richard Sitze

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接