Java:超出范围后线程不会释放

时间:2016-10-06 22:31:19

标签: java out-of-memory executorservice threadpoolexecutor

解决:抱歉,问题与Java线程无关。 C3P0的ComboPooledDataSource正在创建如此多的线程而不是释放它们。切换到DBCP2的BasicDataSource后,线程数不再增加。

我写了一个网络应用程序,因为无法创建更多线程而崩溃。在其中一个函数中,我让ExecutorService创建一个包含10个线程的线程池作为该函数的局部变量。当我监视线程时,每次调用该函数时,都会创建大约12个线程。

然后我将其移动到测试文件并在多个shell中运行:

public static void main(String[] args) throws Exception {
    testRun();

    Thread.sleep(1253234234);
}      

public static testRun() {
   WorkQueue queue = new ThreadPool(10);
     for (int i = 0; i < 10; i++) {
        queue.addJob(new Runnable() {

            @Override
            public void run() {
                System.out.println(this);
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }});
    }
    queue.startJobs();
    queue.wait(10);
}

public void wait(int seconds) {
    executor.shutdown();
    try {
        if (!executor.awaitTermination(seconds, TimeUnit.SECONDS)) {
            throw new RuntimeException("Thread pool terminated unexpectedly due to time out.");
        }
    } catch (InterruptedException ie) {
        throw new RuntimeException("Thread interrupt event is received while waiting for termination of ThreadPool - " + ie.getMessage());
    }
}

这会在每个shell中创建25个线程,然后在完成后仅释放10个线程。因此,每次调用此函数时,都有15个线程未被释放。我猜测15是maxPoolSize,10是corePoolSize。但是为什么在功能结束时它们都不会被释放?

所以我想也许我不理解这个ExecutorService类并编写原始线程:

public static void main(String[] args) throws Exception {
    testRun();

    Thread.sleep(1253234234);
}

private static void testRun() throws Exception {

    for (int i = 0; i < 10; i++) {
        Thread t = new Thread(new Runnable() { 
            @Override
            public void run() {
                try {
                    Thread.sleep(5000);
                    System.out.println(this);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }
}

这些现在为每个shell创建27个线程,并在每个函数完成后释放10个。我究竟做错了什么?如何在函数本地释放这些线程?有人能指出我正确的方式吗?

请在测试后替换测试内容时忽略编译/语法错误,因此不会复制并粘贴工作代码。

谢谢。

0 个答案:

没有答案