【问题标题】:Executor Service Threading执行器服务线程
【发布时间】:2016-12-23 19:05:12
【问题描述】:

我有一个 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. 在这种情况下我必须关闭 Executorservice 吗?我在 Web 服务环境中的情况如何。

以下是我的代码的 sn-p。

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

非常感谢任何建议和帮助!

【问题讨论】:

  • 请改进您问题中的代码格式

标签: java multithreading executorservice


【解决方案1】:

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

该行导致 JVM 创建Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue() 线程。套接字池往往代表它可以创建多少连接,通常在 2000-3000 范围内。您不应该创建那种大小的线程池。

查看您的其余代码,我不完全确定您要对该池做什么。您在新线程中创建套接字,然后阻塞以在原始线程上检索这些套接字。我建议您删除所有添加的线程,因为目前它除了添加更多线程之外什么都不做。

最后,在使用异步处理时,使用Future.get() 几乎总是一个坏主意,因为这会抵消多线程带来的任何好处。必须使用它表明您需要重新考虑您的设计。

【讨论】:

    【解决方案2】:
    1. 为什么会创建这么多线程?
    ExecutorService spool = Executors.newFixedThreadPool(Integer.valueOf(
    GlobalUtils.getAppProp().getString("socketPoolSize")).intValue());
    

    目前您正在创建这么多线程,并且您不应该需要这么多线程。

    在您的属性中检查socketPoolSize 的值,这将回答您的查询。检查服务器中允许的最大进程数,该值应大于socketPoolSize

    看看下面的问题:

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

    1. 在这种情况下我必须关闭 Executorservice 吗?我在 Web 服务环境中的情况。

    是的。无论您的环境如何,您都必须关闭 ExecutorService。请参考以下 SE 问题:

    How to forcefully shutdown java ExecutorService

    【讨论】:

      猜你喜欢
      • 2020-05-18
      • 2017-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-10
      • 2021-06-21
      • 1970-01-01
      相关资源
      最近更新 更多