多线程之线程池「建议收藏」

多线程之线程池「建议收藏」小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。 创建线程会产生系统开销,并且每个线程会占用一定的内存等资源,同时线程的销毁也需要带来一定的压力。过多的线程还会带来由于上下文切换等等的性能损

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。

创建线程会产生系统开销,并且每个线程会占用一定的内存等资源,同时线程的销毁也需要带来一定的压力。过多的线程还会带来由于上下文切换等等的性能损耗。

使用线程池的好处:
1)提高响应速度:通过复用线程可以消除线程创建销毁带来的延迟,提示响应速度
2)降低资源消耗线程池可以统筹内存和CPU的使用,避免资源使用不当,线程池会根据配置和任务数量灵活控制线程数量,不够就创建,多了就回收,避免线程过多导致内存溢出,过少导致资源浪费
3)提高线程可管理行线程池可以统一管理资源,统一进行分配、调优、监控。

一、线程池参数

1.1 线程池核心参数

1)corePoolSize 核心线程数。默认情况核心线程会一直存活。

2)maxPoolSize 最大线程数。决定线程池最多可以创建多少个线程

3)KeepAliveTime+时间单位 设置线程空闲时间,当线程空闲时间超过KeepAliveTime就会被销毁。allowCoreThreadTimeOut 参数可以决定核心线程若空闲时间过长,是否可以被回收

4)ThreadFactory 线程工厂。用来创建新线程,可以对线程的属性进行定制,比如线程group、线程名称、优先级等。

5)workQueue 存放任务的队列,即缓冲队列。

6)Handler 任务被拒绝时的策略 拒绝时机:

  • 调用shutdown等方法关闭线程池后,此时如果再向线程池提交任务,则遭到拒绝
  • 线程池没有能力处理任务时,即线程数达到了maxPoolSize,切workQueue已满

1.2 线程池拒绝策略

拒绝策略统一实现java.util.concurrent.RejectedExecutionHandler java在ThreadPoolExecutor中提供了其4中实现:

  • AbortPolicy 当需要拒接任务时,直接抛出RejectedExecutionException运行时异常
  • DiscardPolicy 当需要拒绝任务时直接丢弃,也不会给任何通知,可能会造成数据丢失
  • DiscardOldestPolicy 当需要拒绝任务时,丢弃任务队列中最长时间未被执行的任务,同样存在数据丢失风险
  • CallerRunsPolicy 当需要拒绝任务时,则将此任务交给提交该任务的线程去执行。不会造成数据丢失,而且当线程池满负载时,新来的任务由提交任务的线程去执行,这样主线程因为执行任务而被占用,也就减缓了提交新任务的速度,而线程池也可再次期间执掉一部分任务,腾出空间,相当于给了线程池一个缓冲期,并且相当于有一个负向反馈。

1.3 线程池常用阻塞队列

  • ArrayBlockingQueue
  • LinkedBlockingQueue
  • SynchronizedQueue 内部没有缓冲区
  • DelayedWorkQueue

三、线程池运行过程

image.png

四、 常见线程池

4.1 FixedThreadPool

固定线程数,无界队列,由于无界队列,会OOM。适用于任务数量不均匀、对内存压力不敏感场景。

4.2 CachedThreadPool

由于maximumPoolSize为Integer,MAX_VALUE,所以最终创建的线程数量会达到操作系统的上限或者导致内存不足。适用于要求低延迟的短期任务场景

4.3 ScheduledThreadPool

适用于定时任务执行场景,支持固定频率和固定延时

4.4 SingleThreadExecutor

单线程线程池,适用于需要一部执行但需要保证任务顺序的场景

  • SingleThreadScheduledExecutor

  • ForkJoinPool 采用分治思想,将大任务分解成多个小任务处理,然后合并结果

五、线程池异常捕获机制

总而言之,使用execute方法提交任务时,异常可以通过线程的UncaughtExceptionHandler机制捕捉异常。 而通过submit方式则不会,因为submit方法会将传入的runnable封装为future,而future内部执行时,直接进行了try catch,因而异常不会被抛出去,因为线程池也就感知不到异常。

www.cnblogs.com/ncy1/articl…

7.4 线程数量应该设置为多少

CPU密集型任务设置为CPU核心数的1~2倍 IO密集型任务公式:CPU核心数*(1+平均等待时间(I/O)/平均工作时间(cpu计算))

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

(0)

相关推荐

  • mysql连接查询和子查询效率_子查询和连接查询性能

    mysql连接查询和子查询效率_子查询和连接查询性能多表连接的基本语法 多表连接,就是将几张表拼接为一张表,然后进行查询 select 字段1, 字段2, … from 表1 {inner|lift|right} join 表2 on 连接条件;

    2023-04-21
    140
  • Python应用之字符串替换功能

    Python应用之字符串替换功能在日常工作中,我们常常需要对文本进行一定的处理。经常会遇到需要用指定的字符串替换文本中的一些特定字符串的情况。比如,我们需要修改文章中某些单词或者短语的拼写错误,或者将一串字符转换为另一串字符。

    2023-12-19
    106
  • 技术译文 | 使用 Docker 安装 MySQL[通俗易懂]

    技术译文 | 使用 Docker 安装 MySQL[通俗易懂]作者:Peter Zaitsev 翻译:管长龙 原文:https://www.percona.com/blog/2019/11/19/installing-mysql-with-docker/ 在工…

    2022-12-20
    129
  • Mybatis官方文档解读「终于解决」

    Mybatis官方文档解读「终于解决」作用域(Scope)和生命周期 理解我们之前讨论过的不同作用域和生命周期类别是至关重要的,因为错误的使用会导致非常严重的并发问题。 SqlSessionFactoryBuilder 这个类可以被实例…

    2023-02-09
    155
  • 搜狐为什么不私有化_搜狐畅游公司地址

    搜狐为什么不私有化_搜狐畅游公司地址中国网科技4月15日讯搜狐官网今日宣布,根据搜狐与其间接全资子公司Sohu.com Limited,及其直接全资子公司Changyou Mer

    2023-07-14
    130
  • Python实现快速计算e的幂次方

    Python实现快速计算e的幂次方对于计算机科学家和数学家来说,常数e是一个非常重要的数,它是自然对数的底数。在一些计算机科学领域中,比如机器学习和数据科学,我们需要不断地计算e的幂次方。然而,对于超大的n值,直接计算e的幂次方是非常耗时的。本文将介绍如何使用Python来实现快速计算e的幂次方的方法。

    2023-12-16
    104
  • Python工程师——cat函数核心使用技巧

    Python工程师——cat函数核心使用技巧在编程中,常常需要读取文件内容,并将其打印到终端或者进行其他操作。对于Linux和Unix操作系统中的开发人员来说,cat函数是一个非常常用的命令。在Python中,也有对应的cat函数可以使用,本文将介绍cat函数的核心使用技巧。

    2024-06-15
    38
  • mysql事务(详解)「终于解决」

    mysql事务(详解)「终于解决」1、事务定义-事务:事务是一个最小的不可在分的工作单元;通常一个事务对应一个完整的业务(例如银行账户转账业务,该业务是一个最小的工作单元)2、事务有四个特性:一致性、持久性、原子性、隔离性…

    2023-04-02
    150

发表回复

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