多线程执行器服务java可能的线程泄漏
我试图运行这个简单的类,并为每个循环计算java进程线程的数量
ppid|wc-l
我在centOS 6.5上测试oracle java 1.8.0_20版
对于每个循环,线程的数量增加了可用处理器()的数量
当ExecutorService在另一个线程中运行时,garbace collector似乎不会释放僵尸线程
如果我创建一个静态执行器服务,它就不会发生
私有静态最终执行者服务执行者=执行者。newFixedThreadPool(Runtime.getRuntime()。可用的处理器());)
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!");
}
}
# 1 楼答案
如果正确地浏览了代码,那么得到多个池对象的原因是因为语句
for循环中的每次执行都将创建 ExecutorService,因为它是ExecutorTest类的成员变量。 即使没有关机,你的程序也会继续运行 线程将不会被GCed,因为它们在 游泳池关闭了
如果将其设为静态变量,则只有一个ExecutorService 类级别内的对象,这就是为什么不获得多个 创建了池对象,所以最好不要关闭池 你会得到一个例外
# 2 楼答案
在run()方法中添加try/finally块,并在finally块中的
executor
上调用shutdownNow()