线程池参数及配置「建议收藏」

线程池参数及配置「建议收藏」线程池-线程池参数及配置在实际项目中线程的应用都会使用线程池来管理,线程池的常用参数及配置学习记录。目录线程池-线程池参数及配置一、线程池在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如果并发的线程数多,并且每个线程都是…

大家好,又见面了,我是你们的朋友全栈君。

线程池-线程池参数及配置

在实际项目中线程的应用都会使用线程池来管理,线程池的常用参数及配置学习记录。


目录

线程池-线程池参数及配置

一、线程池

1、线程池的优势

二、线程池常用参数 ThreadPoolExecutor

1. corePoolSize:核心线程数

2. queueCapacity:任务队列容量(阻塞队列)

3. maxPoolSize:最大线程数

4. keepAliveTime:线程空闲保持时间

5. allowCoreThreadTimeout:允许核心线程超时

6.rejectedExecutionHandler:任务拒绝处理器

三、ThreadPoolExecutor执行过程

四、Java中4种线程池

4.1  newCachedThreadPool

4.2  newFixedThreadPool

4.3  newScheduledThreadPool

4.4  newSingleThreadExecutor

五、Java线程池参数配置

1、线程池的默认值

2、参数配置



一、线程池

        在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在 Java 中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。

       如果并发的线程数多,并且每个线程都是执行一个时间很短的任务就结束了,这样会造成频繁的创建和销毁线程从而导致降低系统的效率。

       线程若是无限制的创建,可能会导致内存占用过多而产生OOM,并且会造成cpu过度切换。

       那么问题来了,有没有办法可用复用创建好的线程呢,也就是线程执行完一个任务后,不被销毁,继续执行其他的任务?

       用线程池来管理多个线程,复用空闲线程,减少线程的创建和销毁,提升系统性能。

1、线程池的优势

(1)降低系统资源消耗,通过重用已存在的线程,降低线程创建和销毁造成的消耗;
(2)提高系统响应速度,当有任务到达时,通过复用已存在的线程,无需等待新线程的创建便能立即执行;
(3)方便线程并发数的管控。因为线程若是无限制的创建,可能会导致内存占用过多而产生OOM,并且会造成cpu过度切换(cpu切换线程是有时间成本的(需要保持当前执行线程的现场,并恢复要执行线程的现场))。
(4)提供更强大的功能,延时定时线程池。

线程池参数及配置「建议收藏」

二、线程池常用参数 ThreadPoolExecutor

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;
    }

1. corePoolSize:核心线程数

1.1 核心线程会一直存活,即使没有任务需要执行。

1.2 当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理。

1.3 设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭。

1.4 可以通过 prestartCoreThread() 或 prestartAllCoreThreads() 方法来提前启动线程池中的基本线程。

2. queueCapacity:任务队列容量(阻塞队列)

2.1  当核心线程数达到最大时,新任务会放在队列中排队等待执行。

3. maxPoolSize:最大线程数

3.1  线程池所允许的最大线程个数

3.2  maxPoolSize>当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务。

3.3  当线程数=maxPoolSize,且任务队列已满时,线程池会根据handle策略处理,默认是AbortPolicy 丢弃任务,抛运行时异常。

4. keepAliveTime:线程空闲保持时间

4.1 当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize。

4.2 如果allowCoreThreadTimeout=true,则会直到线程数量=0。

5. allowCoreThreadTimeout:允许核心线程超时

6.rejectedExecutionHandler:任务拒绝处理器

6.1 两种情况会拒绝处理任务:

(1)当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务。

(2)当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务。线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常。

6.2 ThreadPoolExecutor类有几个内部实现类来处理这类情况-handle饱和策略:

(1)AbortPolicy 丢弃任务,抛运行时异常。

(2)CallerRunsPolicy 执行任务。

(3)DiscardPolicy 忽视,什么都不会发生。

(4)DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务。实现RejectedExecutionHandler接口,也可自定义处理器。

三、ThreadPoolExecutor执行过程

1.当线程数小于核心线程数时,创建线程。

2.当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。

3.当线程数大于等于核心线程数,且任务队列已满。

(1)若线程数小于最大线程数,创建线程。

(2)若线程数等于最大线程数,抛出异常,拒绝任务。

线程池参数及配置「建议收藏」

四、Java中4种线程池

Java通过Executors提供四种线程池,分别为:

4.1  newCachedThreadPool

newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。

newCachedThreadPool:用来创建一个可以无限扩大的线程池,适用于负载较轻的场景,执行短期异步任务。(可以使得任务快速得到执行,因为任务时间执行短,可以很快结束,也不会造成cpu过度切换)

4.2  newFixedThreadPool

newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。

newFixedThreadPool:创建一个固定大小的线程池,因为采用无界的阻塞队列,所以实际线程数量永远不会变化,适用于负载较重的场景,对当前线程数量进行限制。(保证线程数可控,不会造成线程过多,导致系统负载更为严重)

4.3  newScheduledThreadPool

newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。

newScheduledThreadPool:适用于执行延时或者周期性任务。

4.4  newSingleThreadExecutor

newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。

newSingleThreadExecutor:创建一个单线程的线程池,适用于需要保证顺序执行各个任务。

线程池参数及配置「建议收藏」

 

五、Java线程池参数配置

1、线程池的默认值

corePoolSize=1

queueCapacity=Integer.MAX_VALUE

maxPoolSize=Integer.MAX_VALUE

keepAliveTime=60s

allowCoreThreadTimeout=false

rejectedExcutionHandler=AbortPolicy()

2、参数配置

配置参数时需要考虑  CPU密集型任务 、 IO密集型任务 、内存使用率 、下游系统抗并发的能力 

配置参数:
CPU密集型 CPU的核数+1
IO密集型 一般配置 2*CPU的核数
参考公式(某大厂配置):
CPU核数/(1-阻塞系数) 阻塞系数在0.8~0.9之间
比如8核CPU 8/(1-0.9) = 80个线程数

 


参考

https://www.jianshu.com/p/7726c70cdc40

https://baijiahao.baidu.com/s?id=1637828094805085849

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/134846.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 什么是QT?「建议收藏」

    什么是QT?「建议收藏」为学习QT首先必须搞明白的一个问题是,什么是QT,查找资料,对于QT有如下的认识:1.Qt是一个跨平台的C++图形用户界面应用程序框架Qt是面向对象的框架,提供了一种称为signals/slots的安全类型来实现各个元件之间的协同工作。2.Qt是一个跨平台的应用程序开发类库Qt包括多达250个以上的C++类,还替供基于模板的collections,serialization,file,I/Odevice,directorymanagement,date/t

    2022年5月17日
    43
  • 微型计算机的主要因素,微型计算机的性能主要取决于( )。

    微型计算机的主要因素,微型计算机的性能主要取决于( )。【单选题】运用移动平均线研判股价趋势时,股价在一段时间下跌后,若短期均线开始上翘,继而穿越长期均线,形成:【单选题】在完成高度保密和紧急任务时往往不适用的领导方式是()【判断题】汽油和柴油发动机的负荷特性区别在于调节方式不同,汽油机属于质调节,柴油机属于量调节【判断题】为了让烙铁头充分接触焊点,焊接时可适当施加压力。【单选题】按构成空间视线限制的方向性可将植物构成空间分为水平空间和()…

    2022年6月28日
    27
  • 什么叫侧面指纹识别_侧面指纹VS屏下指纹和后置指纹,原来我们都低估了侧面指纹…「建议收藏」

    什么叫侧面指纹识别_侧面指纹VS屏下指纹和后置指纹,原来我们都低估了侧面指纹…「建议收藏」原标题:侧面指纹VS屏下指纹和后置指纹,原来我们都低估了侧面指纹随着科技的发展,手机花式解锁方式也是让人眼花缭乱。最早的指纹解锁就是密码和手势解锁,后来为了增加屏幕屏占比,还采用了屏下指纹和前后置指纹解锁,以及侧面指纹解锁。这么多指纹解锁方式你最喜欢哪个呢?屏下解锁2018年1月,vivo发布全球首款屏下指纹解锁手机,vivoX20UD屏幕指纹版。指纹解锁速度在0.6S左右,与传统指纹识别0…

    2022年8月10日
    6
  • 从零开始安装pytorch,并在pycharm中使用

    从零开始安装pytorch,并在pycharm中使用pytorch安装与使用步骤简述anaconda下载与安装anaconda环境配置anaconda安装pytorch包pycharm运行pytorch环境理解环境步骤简述pytorch是基于torch和Python语言的机器学习库。anaconda是环境与包的管理工具,pytorch的下载需要借助anaconda来完成。另外,安装的anaconda自带Python,因此没安装过Python的小伙伴也不必要再安装Python了。最后anaconda为我们提供了运行环境,为了编写程序的方便,我们还需要一款

    2022年8月26日
    7
  • 狂神说Linux_狂神说docker笔记

    狂神说Linux_狂神说docker笔记Linux在服务器端,很多大型项目都是部署在Linux服务器上利用VM + Centos7搭建本地Linux系统你可以使用 man [命令]来查看各个命令的使用文档,如 :man cp。概念云服务器就是一个远程电脑Linux中一切皆文件根目录/,所有的文件都挂载在这个节点下/bin:bin是Binary的缩写, 这个目录存放着最经常使用的命令。/boot: 这里存放的是启动Linux时使用的一些核心文件,包括一些连接文件以及镜像文件。/dev : dev是Device(设备

    2022年8月9日
    7
  • Django(72)Django认证系统库–djoser「建议收藏」

    Django(72)Django认证系统库–djoser「建议收藏」djoser是什么?作用:Django认证系统的REST实现。djoser库提供了一组DjangoRestFramework视图,用于处理注册、登录、注销、密码重置和帐户激活等基本操作。它适用于

    2022年7月29日
    5

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号