实际开发自定义线程池的使用

实际开发过程中我们经常会用到线程池去执行一些任务,降低频繁创建线程带来的一些性能损耗,现将自己开发过程中自己定义的线程池分享给大家,希望能帮助到大家,同时欢迎大家进行评阅补充

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;

import javax.annotation.PreDestroy;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@Component
public class ExecutorPoolUtil {
    // 核心线程数
    public static final int CORE_POOL_SIZE = Runtime.getRuntime().availableProcessors();
    // 最大线程数
    public static final int MAX_POOL_SIZE = Runtime.getRuntime().availableProcessors() * 2;
    //
    public static final int KEEP_ALIVE_TIME = 60;
    // 最大阻塞队列
    private static final int MAX_QUEUE = 200;

    private static ExecutorService executorService;
    // slfj 日志
    private static final Logger logger = LoggerFactory.getLogger(ExecutorPoolUtil.class);

    static {
        logger.info("开始初始化线程池工具类,核心线程数:{},最大线程数:{},超出线程最大存活时间:{}s", CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME);
        executorService = new ThreadPoolExecutor(CORE_POOL_SIZE, MAX_POOL_SIZE, KEEP_ALIVE_TIME, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(MAX_QUEUE),
                new ThreadFactory() {
                    // 记录线程名称,便于日志排查问题
                    private final AtomicInteger threadNum = new AtomicInteger(1);

                    @Override
                    public Thread newThread(Runnable r) {
                        Thread thread = null;
                        try {
                            thread = new Thread(r);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        thread.setName("ExecutorPoolUtil-thread-" + threadNum);
                        thread.setDaemon(false);
                        thread.setPriority(Thread.NORM_PRIORITY);
                        return thread;
                    }
                }, new WaitPolicy());
        logger.info("初始化线程池结束");
    }

    // 对外提供获得线程池对象方法
    public static ExecutorService getExecutorService() {
        return executorService;
    }

    // 工具类一般将空参构造私有化
    private ExecutorPoolUtil() {
    }

    // 对外提供工具类线程执行方法
    public static void execute(Runnable runnable) {
        Assert.notNull(runnable, "线程池初始化失败,不能执行任务");
        logger.info("executorService.execute 开始执行线程");
        executorService.execute(runnable);
    }

    // 销毁线程池对象
    @PreDestroy
    public void destory() {
        // 线程池拒绝接受新的任务,等待执行中的任务
        executorService.shutdown();
        while (true) {
            // 判断执行中的任务是否结束
            if (executorService.isTerminated()) {
                logger.info("所有线程任务执行结束");
                break;
            }
            // 若任务未执行结束,线程sleep
            try {
                Thread.sleep(5l);
                logger.info("线程尚未执行结束,继续等待。。。");
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
                logger.error(e.getMessage(), e);
            }
        }
    }

    public static boolean isFull() {
        int activeCount = ((ThreadPoolExecutor) executorService).getActiveCount();
        if (MAX_POOL_SIZE == activeCount) {
            return true;
        }
        return false;
    }


    // 自定义拒绝策略(可以选择默认等其他策略,根据业务需求定)
    private static class WaitPolicy implements RejectedExecutionHandler {
        private static final Logger logger = LoggerFactory.getLogger(WaitPolicy.class);

        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {

            try {
                executor.getQueue().offer(r, 60, TimeUnit.SECONDS);
            } catch (InterruptedException e) {
                e.printStackTrace();
                logger.error(e.getMessage(), e);
            }

        }
    }

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值