线程池的使用

首先看看阿里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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,132评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,802评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,566评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,858评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,867评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,695评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,064评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,705评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,915评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,677评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,796评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,432评论 4 322
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,041评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,992评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,223评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,185评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,535评论 2 343

推荐阅读更多精彩内容