情况如下: 我必须使用Xfire与服务器交换数据。服务器无法处理很多并发.50是限制。所以我打算使用ExecutorService来限制并发线程的数量。然后Q& A发现内存的使用是程序运行20分钟后,当它有50个并发时,接近100%。
这是我的代码:
public class CompletionServiceImpl {
private static Logger logger = Logger.getLogger("BackgroundLog");
private int threadNum;
private ExecutorService executor = null;
private CompletionService<Integer> sc = null;
private static CompletionServiceImpl completionServiceImpl = null;
private CompletionServiceImpl(){
this.threadNum = getThreadNum();
this.executor = Executors.newFixedThreadPool(threadNum);
this.sc = new ExecutorCompletionService<Integer>(executor);
}
/***
* get the size of thread pool
***/
private int getThreadNum(){
int threadNum = 5;
Properties props = new Properties();
try {
props.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("tlWeixinconfig.properties"));
threadNum = Integer.parseInt(props.getProperty("THREAD_NUM"));
} catch (IOException e) {
logger.error(e.getMessage(), e);
}
return threadNum;
}
public static CompletionServiceImpl getInstance(){
if(completionServiceImpl == null){
synchronized(CompletionServiceImpl.class){
if(completionServiceImpl == null){
logger.info("thread pool is initialized.");
completionServiceImpl = new CompletionServiceImpl();
}
}
}
return completionServiceImpl;
}
public ExecutorService getExecutor() {
return executor;
}
public CompletionService<Integer> getSc() {
return sc;
}
}
公共类MyCallable实现Callable {
private static Logger logger = Logger.getLogger("BackgroundLog");
private String id;
private String usr;
private String type;
private String expireDate;
private String billingURL;
private int timeout;
private int result;
public MyCallable(String id, String usr,String type, String expireDate, String billingURL,int timeout,int result){
super();
this.id = id;
this.usr = usr;
this.type = type;
this.expireDate = expireDate;
this.billingURL = billingURL;
this.timeout = timeout;
this.result = result;
}
private int newinsertdrawcn(int result)throws Throwable {
try {
URL url = new URL(billingURL);
HttpURLConnection httpConnection = (HttpURLConnection)url.openConnection();
httpConnection.setConnectTimeout(timeout);
httpConnection.connect();
Client client = new Client(httpConnection.getInputStream(), null);
client.setProperty(CommonsHttpMessageSender.HTTP_TIMEOUT, String.valueOf(timeout));
client.setProperty(CommonsHttpMessageSender.DISABLE_KEEP_ALIVE, "true");
client.setProperty(CommonsHttpMessageSender.DISABLE_EXPECT_CONTINUE, "true");
Object[] results = client.invoke("drawcn", new Object[] {id, usr, type, expireDate });
if (results.length > 0) {
result = Integer.parseInt(results[0].toString());
}
} catch (Throwable t) {
throw t;
}
return result;
}
@Override
public Integer call(){
try{
result = newinsertdrawcn(result);
}catch(Throwable t){
logger.error(t.getMessage(),t);
}
return result;
}
}
有人可以解释为什么以及如何解决这个问题吗?
或者是否有人知道如何限制并发线程的数量?
答案 0 :(得分:1)
有两种可能性:
这是由于线程池中有太多线程引起的。每个线程可能有一个2Mb堆栈,活动线程很可能在各自的堆栈上有对象。
这是由内存泄漏引起的,这些内存泄漏会因许多线程处于活动状态而加剧。 (一种可能是由于未正确使用线程局部变量而导致内存泄漏。)
您需要使用内存分析器进行调查。
如何限制并发线程的数量?
简单。减少执行程序的线程池大小。