美文网首页
对于线程池的理解

对于线程池的理解

作者: 倚仗听江 | 来源:发表于2020-09-06 23:04 被阅读0次

线程池的作用:控制线程的数量,处理过程中把任务放到队列中,然后在线程创建后启动这些任务。如果线程数量超过了最大数量,超出的线程等待。等到其他线程执行完毕后,再从队列中取出任务来执行。

线程池的作用:

  • 线程复用
  • 管理线程
  • 控制最大并发

有Java为我们提供了这样三种直接创建线程池的方法,但不推荐使用。因为如果使用这些方式,在出现问题的时候,不容易快速定位到底是哪个线程出的问题。而且它们的任务队列都是LinkedBlockingQueue,这是由链表结构组成的有界(但默认值大小为Integer.MAX_VALUE)阻塞队列。

ExecutorService pool1 = Executors.newSingleThreadExecutor();//一池一线程
ExecutorService pool2 = Executors.newFixedThreadPool(5);//一池五线程
ExecutorService pool3 = Executors.newCachedThreadPool();//一池N线程

顺便提一下阻塞队列吧

当阻塞队列是空的时候,从队列中获取元素的操作会被阻塞;
​当阻塞队列是满的时候,往队列中添加元素的操作会被阻塞。

阻塞队列的种类

  • ArrayBlockingQueue:由数组结构组成的有界阻塞队列
  • LinkedBlockingQueue:由链表结构组成的有界(但默认值大小为Integer.MAX_VALUE)阻塞队列
  • PriorityBlockingQueue:支持优先级排序的无界阻塞队列
  • DelayBlockingQueue:使用优先级队列实现的延迟无界阻塞队列
  • SynchornousQueue:不存储元素的阻塞队列,也即单个元素的队列(即时消费)
  • LinkedTransferQueue:由链表结构组成的无界阻塞队列
  • LinkedBlockingDueue:由链表结构组成的双向阻塞队列

线程池的七大参数:

  1. corePoolSize:线程池中常驻的核心线程数
  2. maxiumPoolSize:能够容纳的最大线程数,必须大于等于1。
  3. keepAliveTime:多余空闲线程的存活时间。当前线程数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余线程会被销毁直到只剩下corePoolSize个线程位置。
  4. unit:keepAliveTime的单位
  5. workQueue:任务队列,被提交但未被执行的任务
  6. threadFactory:生成线程池中工作线程的线程工厂,用于创建线程,默认即可。
  7. handler:拒绝策略,表示当队列满了并且工作线程大于等于最大线程数时,如何拒绝请求。

线程池的工作原理:

  1. 在创建好线程池后,等待提交过来的任务请求
  2. 当调用execute方法添加一个请求任务时,线程池就会做以下判断
    2.1 如果当前运行的线程数量少于corePoolSize,那么马上创建线程运行这个任务
    2.2 如果当前运行的线程数量大于等于corePoolSize,那么将这个任务放进任务队列
    2.3 如果当前任务队列已经满了但是当前运行的线程数量少于maxiumPoolSize,那么就要立即创建非核心线程运行这个任务
    2.4 如果当前任务队列满了并且正在运行的线程数量大于等于maxiumPoolSize,那么线程池就会启动饱和拒绝策略
  3. 当一个线程完成任务后,它会从队列中取下一个任务来执行
  4. 当一个线程无事可做超过一定时间(keepAliveTime),线程池就会判断:如果当前运行的线程数大于corePoolSize,那么这个线程就会被停掉。所以线程池所有任务完成之后,最终会收缩到corePoolSize的大小。

拒绝策略:

当达到最大线程数且等待队列满时,就要启用拒绝策略。

  1. AbortPolicy(默认):直接抛出RejectedException。
  2. CallerRunsPolicy:不会抛弃任务也不会抛出异常,而是回退给调用者
  3. DiscardOldestPolicy:丢弃等待最久的任务。
  4. DiscardPolicy:直接丢弃任务,不做任何处理。

如何合理配置线程数

看是CPU密集型任务还是IO密集型任务

System.out.println(Runtime.getRuntime().availableProcessors());//查看核心数

CPU密集型:CPU核心数 + 1

IO密集型:

  1. CPU核心数 * 2 (IO密集型不是一直在执行任务,所以应该多配置些线程)
  2. CPU核心数/(1 - 阻塞系数) (阻塞系数一般为0.8~0.9)

相关文章

  • 对于线程池的理解

    线程池的作用:控制线程的数量,处理过程中把任务放到队列中,然后在线程创建后启动这些任务。如果线程数量超过了最大数量...

  • 万字长文:带你透彻理解“线程池”

    目标 【理解】线程池的基本概念 【理解】线程池工作原理 【掌握】自定义线程池 【应用】java内置线程池 【应用】...

  • 线程池大小的设置

    线程池大小的设置 这其实是一个面试的考点,很多面试官会问你线程池coreSize 的大小来考察你对于线程池的理解。...

  • 2021-03-10 阿里p6教你理解学习线程池

    阿里p6教你理解学习线程池 对线程或者线程池的理解程度(0-10) 线程:同时运行多个任务,提高任务处理能力 池化...

  • 深入理解Java线程池

    深入理解Java线程池 线程池初探 所谓线程池,就是将多个线程放在一个池子里面(所谓池化技术),然后需要线程的时候...

  • 对于线程和线程池还有线程安全的理解

    进程和线程 进程和线程都是一个时间段的描述,是CPU工作时间段的描述,不过是颗粒大小不同。 他们主要区别是:进程不...

  • J.U.C——线程池专题

    主要讨论以下问题: 认识Java线程池 线程池的种类,区别,和使用场景 线程池的工作流程 线程池几个参数的理解 分...

  • 线程池相关知识

    线程池 1. 什么是线程池 线程的池化,一个线程的容器、集合,包含多个线程 2. 为什么要用线程池 线程对于操作系...

  • Java线程池快速理解

    Java线程池 [toc] 什么是线程池 线程池就是有N个子线程共同在运行的线程组合。 举个容易理解的例子:有个线...

  • Android 线程

    1、线程池的好处?四种线程池的使用场景,线程池的几个参数的理解? 使用线程池的好处在于,是可以减少在创建和销毁线程...

网友评论

      本文标题:对于线程池的理解

      本文链接:https://www.haomeiwen.com/subject/vuzzsktx.html