栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

ThreadPoolExecutor解析

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ThreadPoolExecutor解析

ThreadPoolExecutor解析

最近在研究多线程开发,在构建线程池的时候,常用ThreadPoolExecutor构建,但对于其构造方法中的入参不是很清楚,所以记录一下

ThreadPoolExecutor线程池构建

先上构造方法

    public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue workQueue) {
        this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
             Executors.defaultThreadFactory(), defaultHandler);
    }

这是一个比较基础的构建方法,下面对参数进行剖析

    corePoolSize

    线程池核心线程数,当前线程池中线程数少于corePoolSize的时候,会新建一个线程,放入线程池,并开始执行线程

    maximumPoolSize

    线程池最大线程数,线程池中能创建的最大线程数

    keepAliveTime

    线程池中空闲线程的最大保留时间,过期销毁

    unit

    最大保留时间单位

    workQueue

    线程阻塞队列,当新请求进入时,若当前线程池中线程数大于corePoolSize时,会将线程放入阻塞队列中,等待执行

    线程阻塞有多种方式,这里先使用linkedBlockingDeque进行阻塞,可以设置阻塞队列能放入的线程数

    当超过阻塞队列数时,并且当前线程池存活线程数少于maximumPoolSize时,超过的线程会放入线程池,开始执行,当线程池存活线程数大于maximumPoolSize时,会抛异常RejectedExecutionException

    线程池存活线程数可以通过 threadPoolExecutor.getActiveCount() 获取

上代码

public class TestThread {
    private static final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5, 11, 10, TimeUnit.SECONDS, new linkedBlockingDeque<>(8));

    public static void main(String[] args) {
        for (int i = 0; i < 20; i++) {
            int finalI = i;
            Runnable runnable = () -> {
                System.out.println("线程" + finalI + "加入");
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println("线程" + finalI + "结束");
            };
            threadPoolExecutor.execute(runnable);
            System.out.println("线程池队列:" + threadPoolExecutor.getQueue().size());
            System.out.println("活动线程:" + threadPoolExecutor.getActiveCount());
        }
        threadPoolExecutor.shutdown();
    }
}

代码运行结果

线程池队列:0
线程0加入
活动线程:1
线程池队列:0
活动线程:2
线程1加入
线程池队列:0
活动线程:3
线程2加入
线程池队列:0
活动线程:4
线程3加入
线程池队列:0
活动线程:5
线程4加入
线程池队列:1
活动线程:5
线程池队列:2
活动线程:5
线程池队列:3
活动线程:5
线程池队列:4
活动线程:5
线程池队列:5
活动线程:5
线程池队列:6
活动线程:5
线程池队列:7
活动线程:5
线程池队列:8
活动线程:5
线程池队列:8
活动线程:6
线程13加入
线程池队列:8
活动线程:7
线程14加入
线程池队列:8
活动线程:8
线程15加入
线程池队列:8
活动线程:9
线程16加入
线程池队列:8
活动线程:10
线程17加入
线程池队列:8
活动线程:11
线程18加入
Exception in thread "main" java.util.concurrent.RejectedExecutionException: Task com.guozhaoning.shop.TestThred$$Lambda$1/485815673@5e8c92f4 rejected from java.util.concurrent.ThreadPoolExecutor@61e4705b[Running, pool size = 11, active threads = 11, queued tasks = 8, completed tasks = 0]
	at java.util.concurrent.ThreadPoolExecutor$AbortPolicy.rejectedExecution(ThreadPoolExecutor.java:2063)
	at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:830)
	at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1379)
	at com.guozhaoning.shop.TestThred.main(TestThred.java:32)
线程4结束
线程13结束
线程18结束
线程7加入
线程2结束
线程8加入
线程1结束
线程9加入
线程3结束
线程10加入
线程16结束
线程17结束
线程0结束
线程14结束
线程15结束
线程12加入
线程11加入
线程6加入
线程5加入
线程10结束
线程5结束
线程9结束
线程6结束
线程8结束
线程11结束
线程12结束
线程7结束

可以看出代码会抛出异常,这是因为需要创建的线程已经超过线程池最大数量,线程池会拒绝

计算能创建的实际最大线程数 (线程持续运行条件下)

为什么会提出这个问题?

因为在运行代码的时候,发现我设置的最大线程数是11,但是时间上是创建并且运行成功了19个线程,这个数字是怎么来的,有必要记录一下

首先能够直接创建的线程是是corePoolSize = 5,第6个至第13个线程共8个线程会放入阻塞队列,资源释放后会执行,那么第14个线程怎么处理?这个时候就需要找存活线程数量与线程池最大线程数,当前存活线程是5 ,5是之前放入线程池的5个线程,而线程池中最大线程是11,那么从第十四个线程开始,将放入线程池,不再放入阻塞队列,还能再放6个,所以一共创建的线程是 5 + 8 + 6 = 19

也就是 corePoolSize + workQueueNum + (maximumPoolSize - corePoolSize)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/736845.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号