ExecutorService java可能是线程泄漏

时间:2015-05-05 18:21:49

标签: java multithreading executorservice

我正在尝试运行这个简单的类,对于每个cicle,我都在计算java进程线程的数量。

ps huH p pid | wc -l <​​/ strong>。

我正在使用oracle java版本1.8.0_20 centOS 6.5 进行测试。

对于每个cicle,的线程数增加 availableProcessors()的数量

当ExecutorService在另一个线程内运行时,似乎garbace收集器不会释放僵尸线程。

如果我创建一个静态的ExecutorService,它就不会发生

private static final ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime()。availableProcessors());)。

import java.util.ArrayList;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;

public class ExecutorTest implements Runnable{

private ExecutorService executor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
private static final int CICLE_NUMBERS=100;
private static final int WAIT_SECONDS=20;

@Override
public void run() {
    try{
    ArrayList<Future<DummyThread>> responses = new ArrayList<>();
    for(int i=0;i<CICLE_NUMBERS;i++)
        responses.add((Future<DummyThread>) executor.submit(new DummyThread()));
    for (Future<DummyThread> future : responses)
        future.get(WAIT_SECONDS, TimeUnit.SECONDS);
    }
    catch(Exception e){
        e.printStackTrace();
    }
    System.gc();
}

public static void main(String[] args) throws InterruptedException {
    for(;;){
        new Thread(new ExecutorTest()).start();
        Thread.sleep(2000);
    }
}
}

class DummyThread implements Runnable{

@Override
public void run() {
    System.out.println("Hello World!");
}

}

2 个答案:

答案 0 :(得分:1)

在run()方法中添加try / finally块,并在finally块中的shutdownNow()上调用executor

答案 1 :(得分:0)

如果你正确地检查了代码,你得到多个池对象的原因是由于语句

new Thread(new ExecutorTest()).start();

for循环中的每个执行都将创建一个新的实例 ExecutorService,因为它是ExecutorTest类的成员变量。 你的程序即使没有关机也会继续运行 线程将不会被GC,因为它们还活着并一直工作到 游泳池关闭。

如果你把它变成一个静态变量,那么只有一个ExecutorService 类级别内的对象,这就是为什么你不会得到多个 创建池对象,以便最好不要关闭其他池 你会得到一个例外。