2016-12-23 99 views
0

我有一個REST Webservices通過套接字調用從遺留系統獲取結果來處理它的請求。Executor服務線程

由於有4個插座可用,因此我設置了一個Executorservice且沒有4個線程排隊等待這些連接。該服務最初運行正常,但性能在一段時間後開始下降;我使用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 

問題:

  1. 爲什麼會出現這麼多線程產生的?
  2. 在這種情況下,我是否必須關閉Executorservice?我如何在Web服務環境中工作?

以下是我的代碼片段。

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); 
    } 
} 

非常感謝您的任何建議和幫助!

+0

請改善您的問題中的代碼格式 – larsgrefer

回答

0

Executors.newFixedThreadPool(Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue());

這條線使JVM創建Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue()線程。套接字池往往代表它可以創建多少個連接,並且通常在2000-3000範圍內。您不應該創建該大小的線程池。

看看你的代碼的其餘部分我不完全確定你正在試圖用這個池。您可以在新線程中創建套接字,但是會阻止在原線程上檢索這些套接字。我建議你刪除所有已添加的線程,因爲此刻它什麼也不做,只是添加更多的線程。

最後,當使用異步處理時,使用Future.get()幾乎總是一個壞主意,因爲它否定了多線程的好處。必須使用它表明您需要重新考慮您的設計。

0
  1. 爲什麼我會創建這麼多的線程?
ExecutorService spool = Executors.newFixedThreadPool(Integer.valueOf(
GlobalUtils.getAppProp().getString("socketPoolSize")).intValue()); 

目前正在創建的多個線程,你不應該要求那些許多線程。

檢查您的屬性中的值socketPoolSize,這將回答您的查詢。檢查允許在你的服務器的最大進程數和值應大於socketPoolSize

在以下問題看一看:

"java.lang.OutOfMemoryError : unable to create new native Thread"

  • 我是否在這種情況下必須關閉Executorservice?我如何在Web服務環境中工作?
  • 是的。無論您的環境如何,您都必須關閉ExecutorService。請參閱下面的SE問題:

    How to forcefully shutdown java ExecutorService