编码技巧——自定义线程池

线程池在编码中属于常用类,阿里巴巴编码规范告诉我们需要显示的声明线程池;

当然,临时的异步处理也可以使用JDK8的ComletableFuture的ForkJoinPool;

这里给一个定义线程池的模板代码:

    /**
     * 异步发消息的线程池
     */
    private final ExecutorService executorService = new ThreadPoolExecutor(5, 10, 60, TimeUnit.SECONDS,
            new ArrayBlockingQueue<>(100),
            r -> {
                Thread thread = new Thread(r);
                thread.setName("rmqSenderThread");
                //设置异常捕获器
                thread.setUncaughtExceptionHandler((t, e) -> log.error("[message]async_send_message error! e:{}", e.getMessage()));
                return thread;
            }, new ThreadPoolExecutor.AbortPolicy());

不同的业务场景,可能需要不同的线程池,线程池不能任意复用,要做好线程池隔离;

注意到,传入线程池构造函数的ThreadFactory接口,是为了告诉线程池如何实例化一个新的线程,以及这个线程的属性(如名称、异常捕获器等),具备复用性,因此可以自己实现ThreadFactory接口,来简化ThreadPoolExecutor的ThreadFactory参数:

import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicLong;

/**
 * @author AA
 */
public class ThreadFactoryImpl implements ThreadFactory {

    private final AtomicLong threadIndex = new AtomicLong(0);
    private final String threadNamePrefix;
    private final boolean daemon;

    public ThreadFactoryImpl(final String threadNamePrefix) {
        this(threadNamePrefix, false);
    }

    public ThreadFactoryImpl(final String threadNamePrefix, boolean daemon) {
        this.threadNamePrefix = threadNamePrefix;
        this.daemon = daemon;
    }

    @Override
    public Thread newThread(Runnable r) {
        Thread thread = new Thread(r, threadNamePrefix + this.threadIndex.incrementAndGet());
        thread.setDaemon(daemon);
        return thread;
    }
}

我们一般使用线程池工厂,方便取出对应业务的线程池

import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @Author AA
 * @CreateDate 2019/12/11
 */
public class ExecutorManager {

    private static final Map<Integer, ExecutorService> executorServiceMap = Maps.newConcurrentMap();

    {
        executorServiceMap.put(BenefitTypeEnum.NONTHRESHHOLD_TICKET.getBenefitType(), sendTicketExecutor);
        executorServiceMap.put(BenefitTypeEnum.ONDEMAND_TICKET.getBenefitType(), sendTicketExecutor);
        executorServiceMap.put(BenefitTypeEnum.DISCOUNT_TICKET.getBenefitType(), sendTicketExecutor);
        executorServiceMap.put(BenefitTypeEnum.GAME_BENEFIT_PKG.getBenefitType(), sendGiftExecutor);
        executorServiceMap.put(BenefitTypeEnum.GAME_BENEFIT_TICKET.getBenefitType(), sendGiftExecutor);
        executorServiceMap.put(BenefitTypeEnum.MEMBER_POINT.getBenefitType(), sendPointExecutor);
        executorServiceMap.put(BenefitTypeEnum.MALL_TICKET.getBenefitType(), sendCouponExecutor);
        executorServiceMap.put(BenefitTypeEnum.THEME_TICKET.getBenefitType(), sendTicketExecutor);
        executorServiceMap.put(BenefitTypeEnum.EBOOK_EXCHANGECODE.getBenefitType(), sendExchangeCodeExecutor);
        executorServiceMap.put(BenefitTypeEnum.PAY_COUPON.getBenefitType(), sendCouponExecutor);
    }

    public static ExecutorService getExecutorService(int benefitType) {
        ExecutorService executorService = executorServiceMap.get(benefitType);
        return executorService == null ? sendTicketExecutor : executorService;
    }

    /**
     * 礼券发放线程池
     * @return
     */
    private static final ExecutorService sendTicketExecutor = new ThreadPoolExecutor(10, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(10000), new ThreadFactoryImpl("task-sendTicket"),
                new ThreadPoolExecutor.AbortPolicy());

    /**
     * 积分发放线程池
     * @return
     */
    private static final ExecutorService sendPointExecutor = new ThreadPoolExecutor(10, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(3000), new ThreadFactoryImpl("task-sendPoint"),
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * 优惠券发放线程池
     * @return
     */
    private static final ExecutorService sendCouponExecutor = new ThreadPoolExecutor(10, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(10000), new ThreadFactoryImpl("task-sendCoupon"),
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * 礼包发放线程池
     * @return
     */
    private static final ExecutorService sendGiftExecutor = new ThreadPoolExecutor(10, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(3000), new ThreadFactoryImpl("task-sendGift"),
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * 兑换码发放线程池
     * @return
     */
    private static final ExecutorService sendExchangeCodeExecutor = new ThreadPoolExecutor(10, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(3000), new ThreadFactoryImpl("task-sendExchangeCode"),
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * 任务线程池
     * @return
     */
    public static final ExecutorService taskExecutor = new ThreadPoolExecutor(10, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(10000), new ThreadFactoryImpl("task-schedule"),
            new ThreadPoolExecutor.AbortPolicy());

    /**
     * 移动积分任务线程池
     * @return
     */
    public static final ExecutorService mobilePointExecutor = new ThreadPoolExecutor(10, 100, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<>(3000), new ThreadFactoryImpl("task-mobile-point"),
            new ThreadPoolExecutor.AbortPolicy());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值