Java interface ExecutorService -- Practice.

前几天, 写完一个幕后扫描程序, 由于业务存在多对多的站点关系, 为了程序逻辑简单化, 牺牲掉一些硬件资源 来动态创建N个线程池(是池子哦).

结果悲剧发现: 公司服务器资源耗尽, 其它应用都跑不了, 系统宕机, 运维同事用不了命令.
幸好, 幸好, 有经验丰富的压力测试的同事帮顶住了, 结果2分钟解决BUG, 哈哈!
题外话, 技术组人员配置一定要有经验丰富的~

1.程序日志, 没有任何异常, 因为都是些普通业务, JMX 重型编程 没有在本程序中使用.
2.系统日志:
automount[4228]: expire_proc: expire thread create for /misc failed
automount[4228]: expire_proc: expire thread create for /misc failed
automount[4228]: expire_proc: expire thread create for /net failed
automount[4228]: expire_proc: expire thread create for /misc failed
automount[4228]: expire_proc: expire thread create for /net failed
automount[4228]: expire_proc: expire thread create for /misc failed
automount[4228]: expire_proc: expire thread create for /net failed
automount[4228]: expire_proc: expire thread create for /misc failed
automount[4228]: expire_proc: expire thread create for /net failed
automount[4228]: expire_proc: expire thread create for /misc failed
automount[4228]: expire_proc: expire thread create for /net failed
automount[4228]: expire_proc: expire thread create for /misc failed
automount[4228]: expire_proc: expire thread create for /net failed
automount[4228]: expire_proc: expire thread create for /misc failed
automount[4228]: expire_proc: expire thread create for /net failed
.......................
fork: Resource temporarily unavailable



一看 fork. 我就直接想起 fork/join 并发编程的模型, 也不知道两者是不是有直接关系.

同事, 提醒线程太多 撑爆了系统!
我和同事都认为 Java GC 会 直接回收ExecutorService 对象啊! 事实相反, thread 一多也是很耗资源!
Java Doc :
/*
* An unused ExecutorService should be shut down to allow reclamation of its resources....   
* @since 1.5
* @author Doug Lea
*/


程序结构,修改BUG后:
public class ChecksumsCalculatorServlet extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) {
                AsynService calculator = new AsyncServiceImpl(siteId, nodeName, someInfos,
                        requestCallbackImpl);
                Thread t = new Thread(calculator);
                t.start();
    }
}

public class AsyncChecksumsServiceImpl implements AsyncChecksumsService {
    private ExecutorService threadPool; // 悲剧就在这.
    //init in construct.
    public void run() {
       try{
           // threadPool do something
           // get Future
       }catch(...){
       }finally{
            /**let GC  do its work*/
            threadPool.shutdown(); 
            threadPool = null;
       }
    }
}


总结:
大资源由原来的三个类型 Stream , Connection, GUI 图形对象,
现在增加一个类型interface ExecutorService,
此四类都要用完都要关闭资源!

悲剧源自数据量巨大, GC 不能回收用完的池子, 实战大数据并发编程才开始不久!
经验不足, 只能救助于书了!
并发编程推荐, 读英文好!
Addison.Wesley.Java.Concurrency.in.Practice.May.2006.


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
有应聘"Java工程师/架构师", 请发邮件至: [email protected], 并取得联系.

你可能感兴趣的:(java,thread,bug)