ExecutorThreadHandler 消息处理器


应用场景:消息多线程分发到处理器处理。【备忘】


import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.log4j.Logger;

import com.xx.constant.SystemConfig;


/**
 * 消息处理器
 * @author will_awoke
 * @version 2014-7-16
 * @see ExecutorThreadHandler
 * @since
 */
public final class ExecutorThreadHandler
{

    /**
     * Log
     */
    private static final Logger log = Logger.getLogger(ExecutorThreadHandler.class);

    /**
     * singleton instance
     */
    private static final ExecutorThreadHandler instance = new ExecutorThreadHandler();

    /**
     * msg counter(atomic ThreadSafe)
     */
    private final AtomicInteger counter = new AtomicInteger(0);

    /**
     * 线程池大小 = 当前主机cpu数量 * poolsize
     */
    private static final Integer threadPoolCapacity = (Runtime.getRuntime().availableProcessors())
                                                      * SystemConfig.mqThreadPoolSize;

    /**
     * 线程池
     */
    private static final ExecutorService threadPool = Executors.newFixedThreadPool(threadPoolCapacity);

    /**
     * newly created single-threaded Executor
     * 创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。
     * 如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。
     */
    private static final ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();

    /**
     * singleHandler for singleThreadExecutor
     */
    private final HandlerThread singleHandler = new HandlerThread();

    /**
     * 线程池内部对象集合
     */
    private static final List<HandlerThread> handlerThreadList = new ArrayList<HandlerThread>();

    static
    {
        // 初始化线程池内部对象
        for (int i = 0; i < threadPoolCapacity; i++ )
        {
            handlerThreadList.add(new HandlerThread());
        }

        // shutdown hook
        Runtime.getRuntime().addShutdownHook(new Thread()
        {
            @Override
            public void run()
            {
                threadPool.shutdown();
            }
        });
    }

    /**
     * 消息处理线程
     */
    static class HandlerThread extends Thread
    {
        // 阻塞队列,初始化容量 FIFO
        private BlockingQueue<Object> queue = new LinkedBlockingQueue<Object>(
            SystemConfig.mqQueueCapacity);

        HandlerThread()
        {}

        /**
         * 将消息添加到阻塞队列中
         * @param msg 
         * @see
         */
        void put(Object msg)
        {
            try
            {
                log.info(getName() + " mqHandlerThread put msg : " + msg.toString());

                // 阻塞put
                queue.put(msg);
            }
            catch (InterruptedException e)
            {
                Thread.currentThread().interrupt();
            }
        }

        @Override
        public void run()
        {
            // 监听是否有新消息到达,有则立即处理,无则阻塞。
            while (true)
            {
                try
                {
                    // 消息交予后续处理 
                    Object takeMsg = queue.take();

                    log.info(Thread.currentThread().getName() + " mqHandlerThread take msg : "
                             + takeMsg.toString());

                    //HandlerFactory.handle(takeMsg);//handler工厂处理
                }
                catch (InterruptedException e)
                {
                    Thread.currentThread().interrupt();
                }
            }
        }
    }

    /**
     * core handler method (not static)
     * @param msg  msg that needs dispatch to the server
     * @see
     */
    public void handler(Object msg)
    {
        // 以原子方式将当前值加 1,返回更新后的值(即消息计数器+1)
        int currentCounterVal = counter.incrementAndGet();

        // 消息计数器对线程池容量取余,以保障消息尽可能的平均分配到每个线程进行处理
        int listIndex = currentCounterVal % threadPoolCapacity;
        HandlerThread run = handlerThreadList.get(listIndex);
        log.debug("currentCounterVal " + currentCounterVal + " handlerThreadList index "
                  + listIndex);

        // 线程池执行当前线程
        threadPool.execute(run);

        // 将消息put到线程内部阻塞队列中,等待处理即可
        run.put(msg);
    }

    /**
     * 特殊的消息放到单线程串行化处理,以保证并发安全。
     * @param msg  msg that needs dispatch to the server for singleThread
     * @see
     */
    public void handlerSingleThread(Object msg)
    {
        // single线程池执行 singleHandler
        singleThreadExecutor.execute(singleHandler);
        
        // 将消息put到线程内部阻塞队列中,等待处理即可
        singleHandler.put(msg);
    }

    /**
     * singleton
     * @return
     * @see 
     */
    public static ExecutorThreadHandler getInstance()
    {
        return instance;
    }

    /**
     * private
     */
    private ExecutorThreadHandler()
    {

    }

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值