通过ThreadPoolExecutor来自定义创建线程池

在阿里巴巴JAVA开发手册中有这样一个强制要求。

那么我们如何通过ThreadPoolExecutor来自定义线程池了?

位于java.util.concurrent.ThreadPoolExecutor类的构造器主要有如下几个参数

1.corePoolSize   核心线程数

2.maximumPoolSize 最大线程数

3.keepAliveTime 空闲线程保持激活时间

4.unit 空闲线程保持激活时间单元

5.workQueue 工作队列

扫描二维码关注公众号,回复: 10664725 查看本文章

6.rejectedExecutionHandler 任务拒绝处理器

然后来看下线程池的主要工作原理:

1.现在使用了线程池创建了一个任务,首先判断当前任务数是否大于核心线程数,如果未大于则新建线程

2.如果大于核心线程数,则判断当前任务队列是否已满,如果未满,则放入到任务队列进行等待

3.如果任务队列已满,并且队列不是无界队列,则判断是否超过了最大线程数,如果未超过,则创建临时线程

4.如果超过了最大线程数,则执行任务拒绝策略。

我们可以根据我们机器的配置以及实际的业务场景来设置这些参数。

这里我们新建一个ThreadPoolExecutorPool来自定义线程池

上代码:

import org.apache.commons.lang3.concurrent.BasicThreadFactory;
import org.springframework.util.StringUtils;

import java.util.Map;
import java.util.concurrent.*;

public class ThreadPoolExecutorUtil {

    private static volatile ThreadPoolExecutorUtil INSTANCE;

    private ThreadPoolExecutorUtil(){}

    private static Map<String,ExecutorService> executorServiceMap = new ConcurrentHashMap<>();

    public static ThreadPoolExecutorUtil getInstance() {
        if (INSTANCE == null) {
            synchronized (ThreadPoolExecutorUtil.class) {
                if (INSTANCE == null) {
                    return new ThreadPoolExecutorUtil();
                }
            }
        }
        return INSTANCE;
    }

    /**
     *
     * @param corePoolSize 核心线程数
     * @param maximumPoolSize 最大线程数
     * @param keepAliveTime 线程保持激活时间
     * @param unit 空闲线程等待单元
     * @param workQueueSize 工作队列大小
     * @param poolName 线程池名字
     * @return 线程池
     */
    public ExecutorService getThreadPoolExecutor(int corePoolSize,int maximumPoolSize,
                                                           long keepAliveTime,TimeUnit unit,
                                                           int workQueueSize,
                                                           String poolName) {
        if (corePoolSize <= 0 || corePoolSize > maximumPoolSize ||
                StringUtils.isEmpty(poolName) ||workQueueSize <= 0) {
            throw new IllegalArgumentException("getThreadPoolExecutor argument illegal.");
        }
        if (executorServiceMap.containsKey(poolName)) {

            return executorServiceMap.get(poolName);
        }
        return new ThreadPoolExecutor(corePoolSize,maximumPoolSize,keepAliveTime,unit,
                new LinkedBlockingQueue<>(workQueueSize),
                new BasicThreadFactory.Builder().namingPattern(poolName).daemon(false).build(),
                new ThreadPoolExecutor.AbortPolicy());
    }

}

ps:这里我使用的是LinkedBlockingQueue队列,这个是无界队列,这里我们加入了一个线程池名字的参数,相同名字的线程池这里使用单例模式,将其放入到ConcurrentHashMap中,key为名字,value为线程池。

那怎么去使用了?

见如下demo:

import java.util.concurrent.ExecutorService;
import java.util.concurrent.TimeUnit;

public class MyThreadPoolDemo {


    private static ExecutorService executorService = ThreadPoolExecutorUtil.getInstance().getThreadPoolExecutor(4,20,
            2000L,TimeUnit.SECONDS,200,"My Thread.");

    public static void main(String[] args) {
        MyThreadPoolDemo.invokeThreadPool();;
    }

    public static void invokeThreadPool() {
        executorService.execute(()->{
            System.out.println("当前线程: "+Thread.currentThread().getName());
            for(int i = 0 ; i < 10 ; i++) {
                System.out.println("当前值是: "+i);
            }
        });
        executorService.shutdown();
    }

}
发布了8 篇原创文章 · 获赞 0 · 访问量 316

猜你喜欢

转载自blog.csdn.net/yancun93/article/details/104037942