使用ExecutorService作为局部变量时,一定要在用完后记得shutDown,否则会出有关问题
使用ExecutorService作为局部变量时,一定要在用完后记得shutDown,否则会出问题
ExecutorService 比较重,牵扯到线程,对线程的GC和GC常规对象是有很大的不同
最佳实践,
如果对象提供了shutdown,close等方法,一定要记得在用完后调用这些方法以释放资源,否则会出现资源泄露的情况
package com.qbao.app.test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @author chen.kuan 2016年5月17日 * */ public class GCThreadPool { public static void main(String[] args) { while (true) { try { ExecutorService service = Executors.newFixedThreadPool(1); service.submit(new Runnable() { public void run() { try { Thread.sleep(2); } catch (InterruptedException e) { } } }); service = null; } catch (Exception e) { } try { Thread.sleep(2); } catch (InterruptedException e) { } } } }
================
可以看到线程数量直线上升,(线程泄露)最后出现无法new新线程的情况
Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread at java.lang.Thread.start0(Native Method) at java.lang.Thread.start(Thread.java:714) at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:950) at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1357) at java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:112) at com.qbao.app.test.GCThreadPool.main(GCThreadPool.java:16)
------------------
加入shutdown之后,问题解决
package com.qbao.app.test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; /** * @author chen.kuan 2016年5月17日 * */ public class GCThreadPool { public static void main(String[] args) { while (true) { try { ExecutorService service = Executors.newFixedThreadPool(1); service.submit(new Runnable() { public void run() { try { Thread.sleep(2); } catch (InterruptedException e) { } } }); service.shutdown(); service = null; } catch (Exception e) { } try { Thread.sleep(10); } catch (InterruptedException e) { } } } }