[英]Executor Service Threading
我有一個REST Web服務,通過套接字調用從舊系統中獲取結果來處理其請求。
由於有4個可用的套接字,因此我設置了沒有4個線程的Executorservice
來排隊此類連接。 該服務最初運行正常,但是一段時間后性能開始下降; 我使用jconsole,發現它正在創建> 3000個線程,最后出現以下錯誤:
SEVERE: Servlet.service() for servlet [jersey-serlvet] in context with
path [/DCardServices] threw exception [java.lang.OutOfMemoryError:
unable to create new native thread] with root cause
java.lang.OutOfMemoryError: unable to create new native thread
問題:
以下是我的代碼片段。
ExecutorService spool = Executors.newFixedThreadPool(Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue());
ExecutorService executorService = Executors.newFixedThreadPool(4);
public Response queforTdmProcess(JSSigData jsData) {
return sndWSResponse(jsData.processCardResp1(executorService.submit(new TdmSocketRequest(jsData,socketQueue, spool)).get()));
}
public class TdmSocketRequest implements Callable<String> {
Socket s = getSocketFromPool();
/* connection to socket and get data */
retSocketToPool(s);
}
public Socket getSocketFromPool() {
try {
conSocketConsumer sckconsumer = new conSocketConsumer(getSocketQueue());
Future<Socket> future = getSpool().submit(sckconsumer);
Socket s = future.get();
System.out.print("Getting socket " + s.getLocalPort() + " from the pool" + "\n");
return s;
} catch (Exception e) {
// TODO: handle exception
}
return null;
}
public void retSocketToPool(Socket s) {
conSocketProducer sckProducer = new conSocketProducer(getSocketQueue(),s);
System.out.print("Returning socket " + s.getLocalPort() + " to the pool" + "\n" );
getSpool().submit(sckProducer);
}
}
提前非常感謝您的任何建議和幫助!
Executors.newFixedThreadPool(Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue());
該行導致JVM創建Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue()
線程。 套接字池傾向於表示它可以創建多少個連接,通常在2000-3000范圍內。 您不應該創建該大小的線程池。
查看其余的代碼,我不完全確定您要使用該池做什么。 您在新線程中創建套接字,然后阻塞以在原始線程上檢索那些套接字。 我建議您刪除所有已添加的線程,因為目前除了添加更多線程外,它什么都不做。
最后,在使用異步處理時,使用Future.get()
幾乎總是一個壞主意,因為它抵消了多線程帶來的任何好處。 必須使用它表示您需要重新考慮設計。
- 為什么我創建了這么多線程?
ExecutorService spool = Executors.newFixedThreadPool(Integer.valueOf(
GlobalUtils.getAppProp().getString("socketPoolSize")).intValue());
當前,您正在創建那么多線程,並且您不應該需要那么多線程。
檢查屬性中的socketPoolSize
的值,它將回答您的查詢。 檢查服務器中允許的最大進程數,並且該值應大於socketPoolSize
看看下面的問題:
“ java.lang.OutOfMemoryError:無法創建新的本機線程”
- 在這種情況下,我是否必須關閉Executor服務? 我在Web服務環境中的情況如何。
是。 無論您的環境如何,都必須關閉ExecutorService。 請參閱以下SE問題:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.