简体   繁体   English

执行器服务线程

[英]Executor Service Threading

I have a REST Webservices processing its request by getting result from the legacy system via socket calling. 我有一个REST Web服务,通​​过套接字调用从旧系统中获取结果来处理其请求。

Since there are 4 sockets available, I setup a Executorservice with no of 4 threads to queue for such connections. 由于有4个可用的套接字,因此我设置了没有4个线程的Executorservice来排队此类连接。 The service initially runs ok, but performance starts to degrade after a while; 该服务最初运行正常,但是一段时间后性能开始下降; which I use jconsole and found that it is creating > 3000 threads and finally ended with the following errors: 我使用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

Questions: 问题:

  1. Why am I getting so many threads created? 为什么我创建了这么多线程?
  2. Do I have to shutdown the Executorservice in this case?? 在这种情况下,我是否必须关闭Executor服务? How as I am in a Web service environment. 我在Web服务环境中的情况如何。

Following is a snippet of my code. 以下是我的代码片段。

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

Thanks a great deal in advance for any suggestions and help! 提前非常感谢您的任何建议和帮助!

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

That line causes the JVM to create Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue() threads. 该行导致JVM创建Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue()线程。 Socket pools tend to represent how many connections it can create and are usually in the 2000-3000 range. 套接字池倾向于表示它可以创建多少个连接,通常在2000-3000范围内。 You should not be creating thread pools of that size. 您不应该创建该大小的线程池。

Looking at the rest of your code I am not entirely sure what you are trying to do with that pool. 查看其余的代码,我不完全确定您要使用该池做什么。 You create sockets in the new threads but then block to retrieve those sockets on the original thread. 您在新线程中创建套接字,然后阻塞以在原始线程上检索那些套接字。 I suggest you remove all the threading you've added because at the moment it does nothing but add more threads. 我建议您删除所有已添加的线程,因为目前除了添加更多线程外,它什么都不做。

Lastly when working with asynchronous processing it is almost always a bad idea to use Future.get() since that negates any benefit from multithreading. 最后,在使用异步处理时,使用Future.get()几乎总是一个坏主意,因为它抵消了多线程带来的任何好处。 Having to use it indicates you need to rethink your design. 必须使用它表示您需要重新考虑设计。

  1. Why am I getting so many threads created? 为什么我创建了这么多线程?
ExecutorService spool = Executors.newFixedThreadPool(Integer.valueOf(
GlobalUtils.getAppProp().getString("socketPoolSize")).intValue());

Currently you are creating those many threads and you should not require those many threads. 当前,您正在创建那么多线程,并且您不应该需要那么多线程。

Check the value of socketPoolSize in your properties and that will answer your query. 检查属性中的socketPoolSize的值,它将回答您的查询。 Check maximum number of processes allowed in your server and that value should be greater than socketPoolSize 检查服务器中允许的最大进程数,并且该值应大于socketPoolSize

Have a look at below question: 看看下面的问题:

"java.lang.OutOfMemoryError : unable to create new native Thread" “ java.lang.OutOfMemoryError:无法创建新的本机线程”

  1. Do I have to shutdown the Executorservice in this case?? 在这种情况下,我是否必须关闭Executor服务? How as I am in a Web service environment. 我在Web服务环境中的情况如何。

Yes. 是。 You have to shutdown ExecutorService irrespective of your environment. 无论您的环境如何,都必须关闭ExecutorService。 Refer to below SE question: 请参阅以下SE问题:

How to forcefully shutdown java ExecutorService 如何强制关闭Java ExecutorService

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM