线程池在编码中属于常用类,阿里巴巴编码规范告诉我们需要显示的声明线程池;
当然,临时的异步处理也可以使用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());