线程池的使用

首先看看阿里java规范中对线程池使用的规范

image.png

不允许使用Executors创建线程池,创建的线程池数量可以为Integer.MAX_VALUE,可能导致OOM
推荐使用
ThreadPoolExecutor创建
看看其4构造方法


image.png

看参数最多的一个,上面的都是调这个方法

       /**
     * Creates a new {@code ThreadPoolExecutor} with the given initial
     * parameters.
     *
     * @param corePoolSize the number of threads to keep in the pool, even
     *        if they are idle, unless {@code allowCoreThreadTimeOut} is set
     * @param maximumPoolSize the maximum number of threads to allow in the
     *        pool
     * @param keepAliveTime when the number of threads is greater than
     *        the core, this is the maximum time that excess idle threads
     *        will wait for new tasks before terminating.
     * @param unit the time unit for the {@code keepAliveTime} argument
     * @param workQueue the queue to use for holding tasks before they are
     *        executed.  This queue will hold only the {@code Runnable}
     *        tasks submitted by the {@code execute} method.
     * @param threadFactory the factory to use when the executor
     *        creates a new thread
     * @param handler the handler to use when execution is blocked
     *        because the thread bounds and queue capacities are reached
     * @throws IllegalArgumentException if one of the following holds:<br>
     *         {@code corePoolSize < 0}<br>
     *         {@code keepAliveTime < 0}<br>
     *         {@code maximumPoolSize <= 0}<br>
     *         {@code maximumPoolSize < corePoolSize}
     * @throws NullPointerException if {@code workQueue}
     *         or {@code threadFactory} or {@code handler} is null
     */
    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        if (corePoolSize < 0 ||
            maximumPoolSize <= 0 ||
            maximumPoolSize < corePoolSize ||
            keepAliveTime < 0)
            throw new IllegalArgumentException();
        if (workQueue == null || threadFactory == null || handler == null)
            throw new NullPointerException();
        this.acc = System.getSecurityManager() == null ?
                null :
                AccessController.getContext();
        this.corePoolSize = corePoolSize;
        this.maximumPoolSize = maximumPoolSize;
        this.workQueue = workQueue;
        this.keepAliveTime = unit.toNanos(keepAliveTime);
        this.threadFactory = threadFactory;
        this.handler = handler;
    }

翻译一下
ThreadPoolExecutor(核心线程大小, 最大线程数,线程保持时间,保持时间单位, 缓存队列,线程工厂,拒绝策略)
前四个比较容易理解,看后面几个就好了
缓存队列:任务多的时候,没有多余线程执行任务,这些任务去队列排队,先进先出的原则,这里队列大小是有限制的,队排满了怎么办,用后面的拒绝策略来处理
线程工厂:
继承java.util.concurrent.ThreadFactory,下面是可用的两个工厂

Executors.defaultThreadFactory();
Executors.privilegedThreadFactory();

拒绝策略:队列满了,后面的任务排不进去怎么处理,四种策略


image.png

1.AbortPolicy(终止策略)
这是一个处理器针对被拒绝的任务 直接抛出RejectedExecutionException异常(任务无法执行抛出异常)

2.DiscardPolicy(丢弃策略)
什么都不做,也不抛出异常

3.DiscardOldestPolicy(丢弃旧任务策略)
一种被拒绝任务的处理程序,它丢弃(workQueue队列)最老的未被处理请求(队列最先被放进去的任务),然后调用e.execute(r)重试执行当前任务(注意依然要走流程),除非执行器关闭,在这种情况下任务被丢弃。

4.CallerRunsPolicy(调用方运行策略)
被拒绝任务的处理程序,它直接由提交任务的线程来运行这个提交的任务,除非executor已关闭,在这种情况下任务被丢弃。

测试一下

import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;

@Slf4j
public class Test {

    private static BlockingQueue blockingQueue = new ArrayBlockingQueue(5);

    private static ExecutorService executorService = new ThreadPoolExecutor(1, 5, 60, TimeUnit.SECONDS, blockingQueue, new ThreadPoolExecutor.AbortPolicy());

    /**
     * 主线程分配任务,任务被拒绝执行后暂停2秒,之后继续分配任务
     *
     * @param args
     * @throws InterruptedException
     */
    public static void main(String[] args) throws InterruptedException {
        for (int i = 1; i < 31; i++) {
            log.debug("第{}个任务", i);
            try {
                test(i);
            } catch (RejectedExecutionException e) {
                log.error("拒绝执行{}", i);
                Thread.sleep(2000);
                log.debug("继续执行{}", i);
                test(i);
            }
        }
    }

    private static void test(final int index) {
        executorService.submit(() -> {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                log.error("InterruptedException", e);
            }
            log.debug("test run {}", index);
        });
        log.debug("队列剩余空间:{}", blockingQueue.remainingCapacity());
    }
}

执行结果
1、核心线程先初始化一个线程
2、第1个任务直接给线程
3、第2-6加入队列,装满了
4、第7-10需创建线程用于执行任务
5、到此队列5个和线程五个一起最多处理10任务,第11个任务拒绝处理,等待中...
6、继续执行,利用释放的线程和队列继续处理(优先使用线程,没有加入队列)...

"F:\Program Files\Java\jdk1.8.0_212\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.1\lib\idea_rt.jar=59703:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2.1\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\Administrator\AppData\Local\Temp\classpath1401389501.jar org.jeecg.modules.Test
16:35:47.264 [main] DEBUG org.jeecg.modules.Test - 第1个任务
16:35:47.317 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:5
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 第2个任务
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 第3个任务
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:3
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 第4个任务
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:2
16:35:47.318 [main] DEBUG org.jeecg.modules.Test - 第5个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:1
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第6个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第7个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第8个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第9个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第10个任务
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:47.319 [main] DEBUG org.jeecg.modules.Test - 第11个任务
16:35:47.319 [main] ERROR org.jeecg.modules.Test - 拒绝执行11
16:35:48.344 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 1
16:35:48.344 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 7
16:35:48.345 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 8
16:35:48.345 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 9
16:35:48.345 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 10
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 继续执行11
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 第12个任务
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:3
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 第13个任务
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:2
16:35:49.320 [main] DEBUG org.jeecg.modules.Test - 第14个任务
16:35:49.321 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:1
16:35:49.321 [main] DEBUG org.jeecg.modules.Test - 第15个任务
16:35:49.321 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:49.321 [main] DEBUG org.jeecg.modules.Test - 第16个任务
16:35:49.321 [main] ERROR org.jeecg.modules.Test - 拒绝执行16
16:35:49.351 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 3
16:35:49.351 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 5
16:35:49.351 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 4
16:35:49.351 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 6
16:35:49.351 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 2
16:35:50.365 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 11
16:35:50.365 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 12
16:35:50.369 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 14
16:35:50.365 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 13
16:35:50.369 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 15
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 继续执行16
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 第17个任务
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:5
16:35:51.333 [main] DEBUG org.jeecg.modules.Test - 第18个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第19个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第20个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第21个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第22个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:3
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第23个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:2
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第24个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:1
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第25个任务
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:0
16:35:51.334 [main] DEBUG org.jeecg.modules.Test - 第26个任务
16:35:51.334 [main] ERROR org.jeecg.modules.Test - 拒绝执行26
16:35:52.348 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 18
16:35:52.348 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 19
16:35:52.348 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 16
16:35:52.348 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 20
16:35:52.348 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 17
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 继续执行26
16:35:53.349 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 24
16:35:53.349 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 25
16:35:53.349 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 23
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:5
16:35:53.349 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 21
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 第27个任务
16:35:53.349 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 22
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 第28个任务
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 第29个任务
16:35:53.349 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:53.350 [main] DEBUG org.jeecg.modules.Test - 第30个任务
16:35:53.350 [main] DEBUG org.jeecg.modules.Test - 队列剩余空间:4
16:35:54.353 [pool-1-thread-1] DEBUG org.jeecg.modules.Test - test run 27
16:35:54.353 [pool-1-thread-5] DEBUG org.jeecg.modules.Test - test run 29
16:35:54.353 [pool-1-thread-3] DEBUG org.jeecg.modules.Test - test run 30
16:35:54.353 [pool-1-thread-4] DEBUG org.jeecg.modules.Test - test run 26
16:35:54.353 [pool-1-thread-2] DEBUG org.jeecg.modules.Test - test run 28
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容