package cn.aofeng.threadpool4j;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import cn.aofeng.common4j.ILifeCycle;

/**
 * 多线程池。
 * 
 * @author <a href="mailto:aofengblog@163.com">聂勇</a>
 */
public class ThreadPoolImpl implements ILifeCycle, ThreadPool {

    private static Logger _logger = Logger.getLogger(ThreadPoolImpl.class);    
    
    ThreadPoolConfig _threadPoolConfig = new ThreadPoolConfig();
    
    Map<String, ExecutorService> _multiThreadPool = new HashMap<String, ExecutorService>();
    private ThreadStateJob _threadStateJob;
    
    private static ThreadPoolImpl _instance = new ThreadPoolImpl();
    
    public static ThreadPoolImpl getInstance() {
        return _instance;
    }
    
    @Override
    public void init() {
        _threadPoolConfig.init();
        
        Collection<ThreadPoolInfo> threadPoolInfoList = _threadPoolConfig.getThreadPoolConfig();
        for (ThreadPoolInfo threadPoolInfo : threadPoolInfoList) {
            BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(threadPoolInfo.getQueueSize());
            ThreadPoolExecutor threadPool = new ThreadPoolExecutor(threadPoolInfo.getCoreSize(), threadPoolInfo.getMaxSize(), 
                    threadPoolInfo.getThreadKeepAliveTime(), TimeUnit.SECONDS, workQueue, 
                    new DefaultThreadFactory(threadPoolInfo.getName()));
            _multiThreadPool.put(threadPoolInfo.getName(), threadPool);
            _logger.info( String.format("initialization thread pool %s successfully", threadPoolInfo.getName()) );
        }
        _logger.info( String.format("initialization %d thread pool successfully", threadPoolInfoList.size()) );
        
        if (_threadPoolConfig.getThreadStateSwitch()) {
            _threadStateJob = new ThreadStateJob(_threadPoolConfig.getThreadStateInterval());
            _threadStateJob.init();
            Thread jobThread = new Thread(_threadStateJob);
            jobThread.setName("threadpool4j-threadstate-job");
            jobThread.start();
            
            _logger.info("thread state statitics job start successfully");
        }
    }
    
    public Future<?> submit(Runnable task) {
        return submit(task, "default");
    }
    
    public Future<?> submit(Runnable task, String threadpoolName) {
        ExecutorService threadPool = _multiThreadPool.get(threadpoolName);
        if (null == task) {
            throw new IllegalArgumentException("task is null");
        }
        if (null == threadPool) {
            throw new IllegalArgumentException( String.format("thread pool %s not exists", threadpoolName) );
        }
        
        if (_logger.isDebugEnabled()) {
            _logger.debug("submit a task to thread pool "+threadpoolName);
        }
        
        return threadPool.submit(task);
    }
    
    @Override
    public ThreadPoolInfo getThreadPoolInfo(String threadpoolName) {
        ThreadPoolInfo info = _threadPoolConfig.getThreadPoolConfig(threadpoolName);
        
        return info.clone();
    }
    
    @Override
    public void destroy() {
        for (Entry<String, ExecutorService> entry : _multiThreadPool.entrySet()) {
            _logger.info("shutdown the thread pool "+entry.getKey());
            entry.getValue().shutdown();
        }
        
        _threadStateJob.destroy();
    }

}

@@ -1100,26 +1100,29 @@
 ) %7B%0A        
-_t
+initT
 hreadPoolCon
@@ -1114,24 +1114,158 @@
 itThreadPool
+();%0A        startThreadStateJob();%0A    %7D%0A    %0A    /**%0A     * %E5%88%9D%E5%A7%8B%E5%8C%96%E6%89%80%E6%9C%89%E7%BA%BF%E7%A8%8B%E6%B1%A0%E3%80%82%0A     */%0A    private void initThreadPool() %7B%0A        _threadPool
 Config.init(
@@ -1266,25 +1266,16 @@
 .init();
-%0A        
 %0A       
@@ -2144,29 +2144,112 @@
 e()) );%0A    
+%7D%0A
     %0A
+    /**%0A     * %E5%88%9D%E5%A7%8B%E5%8C%96%E5%B9%B6%E5%90%AF%E5%8A%A8%E7%BA%BF%E7%A8%8B%E7%8A%B6%E6%80%81%E7%BB%9F%E8%AE%A1Job%E3%80%82%0A     */%0A    private void startThreadStateJob() %7B%0A
         if (
@@ -2541,12 +2541,8 @@
 tate
--job
 %22);%0A

重构。将init方法中的代码分成两个部分：初始化线程池、启动线程状态统计Job线程