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

浅析java线程池

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

浅析java线程池

浅析java线程池

Java线程池

1. 常见的四大线程池2. ThreadPoolExecutor的七大参数3. java四大线池程本质

3.1 Executors.newSingleThreadExecutor简单线程池3.2 Executors.newFixedThreadPool固定线程池3.3 Executors.newScheduledThreadPool 安排3.4 Executors.newCachedThreadPool 缓存 4. 线程池的作用5. 自定义线程池6. 线程池常见问题

Java线程池 1. 常见的四大线程池

Executors.newSingleThreadExecutor();Executors.newFixedThreadPool();Executors.newScheduledThreadPool();Executors.newCachedThreadPool(); 2. ThreadPoolExecutor的七大参数

Int corePoolSize

核心线程数 int maximumPoolSize

最大线程数(线程池中,最多存在多少个线程) long keepAliveTime

保持活跃的时间(在指定时间内,如果没有任务,释放非核心线程) TimeUnit unit

时间单位(参数TimeUnit中的常量) BlockingQueue workQueue

等待队列 ThreadFactory threadFactory

创建线程的工厂 RejectedExectuionHandler handler

拒绝策略 3. java四大线池程本质

java线程池本质上只有一个。无论哪个线程池,都是调用ThreadPoolExecutor创建出来的。线程池有不同的特性,是因为创建线程池的时候,参数不一样。 3.1 Executors.newSingleThreadExecutor简单线程池

​ 调用ThreadPoolExecutor构造函数时的七个参数值。

参数含义参数名称参数类型取值备注
核心线程corePoolSizeint1核心线程数为有且只有一个
最大线程maxNumPoolSizeint1最大线程数量只能存在一个
存活时间keepAliveTimelong0L线程保持活跃时间长度,加上时间单位计时
时间单位unitTimeUnitTimeUnit.MILLISECONDS参数TimeUnit中的常量
等待队列workQueueBlockingQueuelinkedBlockingQueue等待队列长度为Integer.MAX_VALUE(int最大值)

有且只有一个线程工作,队列无穷大,所有的任务,都交个这个线程来处理,不论任务多少,使用线程池中的唯一线程,依次的执行队列中的任务。

当核心线程数和最大线程数相等的时候,保持活跃的时间设置是没有意义的,因为核心线程不会被释放,最大线程数不会超过核心线程数,所以当任务执行完成之后,不会进行线程释放

等待队列 new linkedBlockingQueue() 无界队列,构造方法中的初始长度为Integer.MAX_VALUE(int最大值)

等待队列无穷大,意味着该线程池时没有拒绝策略

    
    public linkedBlockingQueue() {
        this(Integer.MAX_VALUE);
    }
3.2 Executors.newFixedThreadPool固定线程池

​ 调用ThreadPoolExecutor构造函数时的七个参数值,在创建这个线程池的时候,需要指定一个参数,该参数指定的是核心线程数和最大线程数

​ Executors.newFixedThreadPool(int size)

参数含义参数名称参数类型取值备注
核心线程corePoolSizeintsizesize由调用方法时,指定的数量决定
最大线程maxNumPoolSizeintsizesize由调用方法时,指定的数量决定
存活时间keepAliveTimelong0L线程保持活跃时间长度,加上时间单位计时
时间单位unitTimeUnitTimeUnit.MILLISECONDS参数TimeUnit中的常量
等待队列workQueueBlockingQueuelinkedBlockingQueue等待队列长度为Integer.MAX_VALUE(int最大值)

和newSingleThreadExecutor的区别在于,创建线程池时,需要指定一个数量size,size在其内部调用ThreadPoolExecutor构造方法时,作为核心线程数和最大线程数[同样导致活跃时间无效],等待队列也是无穷大

Executors.newFixedThreadPool和newSingleThreadExecutor的唯一区别就是需要指定一个线程数量

3.3 Executors.newScheduledThreadPool 安排

​ 调用ThreadPoolExecutor构造函数时的七个参数值,在创建这个线程池的时候,需要指定一个参数,该参数指定的是核心线程数

​ Executors.newScheduledThreadPool(int corePoolSize)

参数含义参数名称参数类型取值备注
核心线程corePoolSizeintsizesize由调用方法时,指定的数量决定
最大线程maxNumPoolSizeintInteger.MAX_VALUE等于无穷大
存活时间keepAliveTimelong0L线程保持活跃时间长度,加上时间单位计时
时间单位unitTimeUnitNANOSECONDS参数TimeUnit中的常量
等待队列workQueueBlockingQueuenew DelayedWorkQueue()该队列的作用:队列中有等待任务,直接创建新线程

当前线程池,只指定一个初始化的核心线程数,等待队列相当于没有缓存机制,进入队列的任务会立刻创建新的线程来执行任务,由于线程保持存活的时间为0所以,超过核心线程数的线程在执行完任务后,会被释放

当达到核心线程数满了以后,就会创建新的线程,当新开出的线程,在完成任务之后,就会被直接销毁。当前线程池在理论上可以创建无穷个线程

DelayedWorkQueue 队列初始化的时候,长度为0,队列不缓存任务,入队列即刻出队列

3.4 Executors.newCachedThreadPool 缓存

​ 调用ThreadPoolExecutor构造函数时的七个参数值

​ Executors.newCachedThreadPool()

参数含义参数名称参数类型取值备注
核心线程corePoolSizeint0核心线程为0
最大线程maxNumPoolSizeintInteger.MAX_VALUE等于无穷大
存活时间keepAliveTimelong60L [一分钟]线程保持活跃时间长度,加上时间单位计时
时间单位unitTimeUnitTimeUnit.SECONDS参数TimeUnit中的常量
等待队列workQueueBlockingQueueSynchronousQueue该队列的作用:队列中有等待任务,直接创建新线程

当前线程池,没有核心线程数量,有任务的时候,启动线程,在线程任务完成之后,等待60秒,在此期间如果有新的任务,复用线程,如果没有新的任务,超过线程存活时间60秒,则销毁线程

4. 线程池的作用

​ 创建线程消耗的性能消耗比较大,将创建的线程存放起来,在线程执行后,不释放。线程的复用性提高,多任务的时候,其中一个线程执行完毕后,可以直接接受下一个任务,避免了创建线程的性能和时间消耗。

​ 不用每次执行任务的时候,都需要创建线程,线程可以复用的情况下,直接从线程池中获取线程,在线程完成任务后,不被释放,可以接受下一次任务。

​ 举例,一个银行平时只开三个窗口(核心线程数),某天业务量爆发,需要办理业务的人增多。三个窗口每个窗口每次只能帮一个人办理业务,很多人都只能在大厅等待(等待队列),如果大厅坐满了等待的人,银行会觉得需要办理业务的人太多了,于是会多开几个窗口,但不能大于银行本身的窗口最大数,当银行开启了足够多的窗口之后,大厅的人数开始减少。

​ 当大厅左右人都办理完业务离开两分钟之后(保持的活跃时间,时间单位),后开的那些窗口的任务完成了,就会将窗口关闭。

​ 另一种情况,线程池中的所有线程全部处在执行任务的状态。银行所有的窗口,都在处理业务,大厅的人没有减少,反而还在增加,这种情况下,银行需要告知后面来的人,需要换个时间再来办理,在线程池中是拒绝策略。

5. 自定义线程池

使用ThreadPoolExecutor自定义线程池。

线程池在刚创建出来的时候,里面是没有线程的。

在我们向线程池提交任务的时候,线程池才会开始创建线程。

如果核心线程数是10,最大的线程数是20,当我们提交第11个的时候(前十个没有结束),线程池会创建新的线程吗?

线程池创建线程的策略,先把核心线程数填满,然后填满等待队列,等待队列如果满了,就创建新的线程,但是总线程数不能大于最大线程数。

6. 线程池常见问题

线程池刚创建的的时候,内部存在几个线程?

线程池在刚创建的时候,内部没有线程 线程池在创建之后,什么时候才会产生线程?

在程序运行过程中,向线程池提交任务的时候,线程池才会创建线程 如果核心线程数是10,最大线程数是20,当提交第11个任务是(前10个线程执行未结束),线程池会不会创建新的线程?

不会,线程池创建线程的策略,先把核心线程数填满,然后填满等待队列,等待队列如果满了,就创建新的线程,总线程数不能大于最大线程数


核心线程永不销毁


拒绝策略后续继续补充…

做一个记录

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

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

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