我有一个REST Web服务通过套接字调用从遗留系统获取结果来处理其请求。
由于有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
问题:
以下是我的代码片段。
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 :(得分:0)
Executors.newFixedThreadPool(Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue());
该行导致JVM创建Integer.valueOf(GlobalUtils.getAppProp().getString("socketPoolSize")).intValue()
个线程。套接字池倾向于表示它可以创建的连接数,通常在2000-3000范围内。您不应该创建该大小的线程池。
查看其余代码,我不完全确定您要对该池执行的操作。您在新线程中创建套接字,但然后阻止在原始线程上检索这些套接字。我建议你删除你添加的所有线程,因为它除了添加更多线程之外什么都不做。
最后,在使用异步处理时,使用Future.get()
几乎总是一个坏主意,因为它否定了多线程的任何好处。必须使用它表示您需要重新考虑您的设计。
答案 1 :(得分:0)
- 为什么我创建了这么多线程?
醇>
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问题: