我工作在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容器中創建線程是否是一種好的做法。 –