我工作在java web应用程序的后端。我添加了一些多线程来加速大数据检索,并且我使用了一些在此过程中创建的ExecutorServices。不过,我已经读过,在Web应用程序中以这种方式创建线程可能不是一个好主意,并且'com.ibm.websphere.asynchbeans.WorkManager'也许是一个选项。尽管如此,在后端使用似乎不是很友好。根据文档,工作管理器是为使用异步Bean的Java平台企业版(Java EE)应用程序创建的“线程池”。我作为一个非常前端无知的后端家伙,甚至都不知道豆子是什么。看起来工作管理器并不是我想要的,但如果手动创建ExecutorService实际上是一个坏主意,我不确定最佳方法是什么。我应该在后端(java)中使用WorkManager进行多线程吗?
回答
在webapp的后端创建自己的线程是一个坏主意,原因如下:Application Server容器为您管理线程。所以如果你在你的应用程序中创建自己的线程,容器将不知道它们,并且将无法管理它们。因此,如果你管理不当,你的应用程序可能导致内存泄漏和其他线程相关的问题。从理论上讲,最好的方法是在App Server中注册一些线程池,并使用JNDI从容器中请求线程。但它可能是一个矫枉过正的问题。所以有时候,你可能想要管理你自己的线程。所以,在这种情况下ExecutorService
是最好的方式,因为它提供了非常好的API来管理你的线程。只要确保在应用程序关闭时关闭ExecutorService
即可,因此不会留下孤立线程。如果你对此非常小心,那么你可以创建自己的线程。请谨慎使用它们,并且小心您在完成或关闭应用程序时关闭了ExecutorService
。顺便说一句,有ThreadLocal
变量类似的问题。完成后,您绝对必须在其中调用metod remove()
,否则即使您的应用程序已关闭,它们仍会保留在内存中,并且只有Application Server重新启动才能清除它们。这是一个危险的内存泄漏。
只是为了迈克尔Gantman的答案,这是一个相当不错的解释,JavaEE的方法来使容器管理线程池是超级容易真正实现扩大:
@Stateless
public class Foo {
@Asynchronous
@Override
public void doSomething() {
//all calls to this function are asynchronous
}
}
的@Aysnchronous
需要的魔法护理在这里,向容器指定这个函数应该被异步调用,容器的责任是弄清楚它的含义。然后呼唤你的容器管理线程池来执行你的功能很简单,只要:
@Stateless
public class Bar {
@EJB
Foo myFooEJB;
public void businessMethod() {
myFooEJB.doSomething();
}
}
结帐这些更多阅读:javax.ejb.Asynchronous,Asynchronous method invocation。获取也许有点太成细节,因为我知道你正在使用IBM的产品,在JBoss中,你的异步是作为一个子系统配置的一部分,通过指定<async thread-pool-name="poolName"/>
(https://docs.jboss.org/author/display/WFLY8/EE+Subsystem+Configuration) 其中poolName
应该引用池如:
<thread-pools>
<thread-pool name="poolName">
<max-threads count="10"/>
<keepalive-time time="100" unit="milliseconds"/>
</thread-pool>
</thread-pools>
但还有如果你想提交,只是一些任务的ExecutorService可以由容器来管理一个更好的方法:
@Resource
ManagedExecutorService executorService;
@Resource
ManagedScheduledExecutorService scheduledExecutorService;
java.io.PrintWriter out = ...;
void scheduleSomeStuff(){
scheduledExecutorService.schedule(new Runnable() {
@Override
public void run() {
out.println("Print out after roughly 15 seconds.")
}
}, 15, TimeUnit.SECONDS);
executorService.submit(new Callable<Boolean>() {
@Override
public Boolean call() throws Exception {
out.println("Print only once, when the task is run by the executor service's discretion.");
}
};
}
这两种资源,特别是我在这里已经参考,运行在不同的线程池中。在这之前,我原本在这里发布了一些使用@Asynchronous
线程池作为执行程序的东西,但没有必要,因为容器应该已经有一个给你;因此您现在在这里看到更新的答案。
这也可能是JBoss的一个小特性,但在JBoss中,它被配置为子系统managed-scheduled-executor-services
和managed-executor-services
。这两个子系统有他们自己独特的线程池,他们利用。
- 1. Java:我应该在这种情况下使用多线程吗?
- 2. 我应该使用utf-8编码进行在线课程吗?
- 3. 我应该使用RMI进行Java多人游戏吗?
- 4. 我应该在后台线程中使用异步方法吗?
- 5. 我应该如何在Java中使用多线程执行外部命令?
- 6. 我应该在angular1中进行senatize吗?
- 7. 应该在后台进行推文吗?
- 8. 我应该使用单个ODBC环境进行多连接吗?
- 9. 我应该在我的Java应用程序中使用java.net或org.apache.http库进行HTTP吗?
- 10. 我应该在我的Java程序中使用多少内存?
- 11. 我应该在Java多线程中使用哪种数据结构?
- 12. 如何在MATLAB中使用JAVA进行显式多线程?
- 13. Python - 我应该使用线程还是进程进行网络活动?
- 14. 应该/我该如何使用线程来改进Python脚本?
- 15. 我应该在python中使用哪些库进行线性编程?
- 16. 这是我应该停止Java中的线程的方式吗?
- 17. 共享对象和多线程问题。我应该在乎吗?
- 18. 我应该使用Content-Security-Policy HTTP头作为后端API吗?
- 19. 我应该使用SSL来保护CMS后端吗?
- 20. 我应该在反应原生应用程序中使用多个图像吗?
- 21. 在这种情况下我应该使用多线程吗? [红宝石]
- 22. 我应该使用哪个线程或进程?
- 23. 我应该在UI线程中调用`Service`的函数吗?
- 24. 我应该如何处理Java中的多线程?
- 25. 我应该使用C#App.config来进行自定义应用程序设置吗?
- 26. 我应该在Java Web应用程序中使用安全管理器吗?
- 27. 程序使用后应该删除吗?
- 28. 我们应该使用EventQueue.invokeLater进行Java桌面应用程序中的任何GUI更新吗?
- 29. 我应该使用StreamReader/Writer和NetworkStream进行C#服务器/客户端吗?
- 30. 我应该在通过AJAX执行操作方法时使用线程吗?
我会建议创建一个单独的类,它将有一个Executor服务,并在池中有一个固定数量的线程,比如说10.每次创建一个线程时,调用这个单例类并将任务传递给这个执行者服务来执行它。这样你就不会创建大量的线程池,而是共享一个线程池。 –
此外,您可以轮询当前的系统规格/容量,并配置此Threadpool/Singleton执行器以优化性能。 – n247s
@ BandiKishore,@ n247s我认为OP询问在一般情况下在Web容器中创建线程是否是一种好的做法。 –