0

情况是这样的:我必须使用Xfire与服务器交换数据。服务器无法处理太多并发。50是限制。所以我打算使用ExecutorService来限制并发线程的数量。然后问答找到用法程序运行 20 分钟后,并发 50 次时,内存接近 100%。

这是我的代码:

公共类 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;
}

}

谁能解释为什么以及如何解决这个问题?

还是有人知道如何限制并发线程的数量?

4

1 回答 1

1

有两种可能:

  • 这是由于线程池中的线程过多造成的。每个线程可以有一个 2Mb 的堆栈,并且活动线程很可能在它们各自的堆栈上都有对象。

  • 它是由大量线程处于活动状态而加剧的内存泄漏引起的。(一种可能性是由于未正确使用线程局部变量而导致的内存泄漏。)

您需要使用内存分析器进行调查。


如何限制并发线程的数量?

简单的。减小执行器的线程池大小。

于 2013-07-14T15:00:45.440 回答