簡體   English   中英

執行器服務線程

[英]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

問題:

  1. 為什么我創建了這么多線程?
  2. 在這種情況下,我是否必須關閉Executor服務? 我在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);
    }
}

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

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

該行導致JVM創建Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue()線程。 套接字池傾向於表示它可以創建多少個連接,通常在2000-3000范圍內。 您不應該創建該大小的線程池。

查看其余的代碼,我不完全確定您要使用該池做什么。 您在新線程中創建套接字,然后阻塞以在原始線程上檢索那些套接字。 我建議您刪除所有已添加的線程,因為目前除了添加更多線程外,它什么都不做。

最后,在使用異步處理時,使用Future.get()幾乎總是一個壞主意,因為它抵消了多線程帶來的任何好處。 必須使用它表示您需要重新考慮設計。

  1. 為什么我創建了這么多線程?
ExecutorService spool = Executors.newFixedThreadPool(Integer.valueOf(
GlobalUtils.getAppProp().getString("socketPoolSize")).intValue());

當前,您正在創建那么多線程,並且您不應該需要那么多線程。

檢查屬性中的socketPoolSize的值,它將回答您的查詢。 檢查服務器中允許的最大進程數,並且該值應大於socketPoolSize

看看下面的問題:

“ java.lang.OutOfMemoryError:無法創建新的本機線程”

  1. 在這種情況下,我是否必須關閉Executor服務? 我在Web服務環境中的情況如何。

是。 無論您的環境如何,都必須關閉ExecutorService。 請參閱以下SE問題:

如何強制關閉Java ExecutorService

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM