美文网首页Android
大白话聊聊线程池的工作原理和核心参数

大白话聊聊线程池的工作原理和核心参数

作者: c6fe2b312f9d | 来源:发表于2020-03-04 10:23 被阅读0次

目录

1、为啥要使用线程池

2、线程池的工作原理

3、线程池都用哪些核心参数

4.  有界队列下的线程池的工作流程

5.  无界队列下线程池可能带来的问题

大家好,我是四九城最豪横的小耳朵。

今天咱们来用大白话聊聊线程池的工作原理和核心参数。

1. 为啥要使用线程池

如下图,假设有这么一个场景,客户的系统每次调用你的系统接口的时候,你拿到消息直接就开一个线程去处理消息。

有一天,遇到高并发场景,比如客户一秒钟调用了你这个接口几百次,甚至上千次,那么你就会一下子创建几百,甚至几千个线程。

那么你想想这个时候你的系统会怎样,本来创建线程就是很消耗cpu、内存的事情,你一下子创建几百上千个线程,那你的系统是不是可能会突然挂掉啊,或者性能急速下降,各种请求超时。

所以为了应对这种场景,你写代码的时候,肯定是不能执行到某处,就new一个线程去处理,然后啥也不管了。因为你没法决定调用方的请求频率,万一人家一秒钟调用你成百上千次,那就会造成很严重的性能问题了。所以你可以考虑去使用线程池,把上面的架构改一下,如下图:

就是你的系统一开始就创建好一个线程池,里面可以设置几个线程。之后客户的系统调用你系统接口的时候,你就不要每次都new一个线程去处理了,你可以直接把消息放到一个内存队列中,放完之后,你就激活一下线程池,它就会从队列中获取任务然后让池子里的线程去处理了。这样一来,就不会有最开始我们讲的,同一时间你的系统创建大量线程导致系统性能下降甚至宕机的问题了。

2. 线程池的工作原理

那你既然要用线程池,肯定是要了解一下,它底层的工作原理的。

首先来说下线程池的内部组成,它主要是线程+队列组成的。

假如现在你提交了一个任务到线程池,任务会先放到内部队列中。线程池会看当前的线程数量是否大于参数corePoolSize。corePoolSize就是你new线程池的时候填的一个参数。此时,如果当前线程数小于corePoolSize,线程池就会直接new一个新的线程来处理任务。

直到核心线程数量等于corePoolSize个后才会用空闲的线程来处理新任务。

线程池里的线程执行完任务是不会死掉的,它会尝试从内部队列中读取新的任务。如果没有任务了,那线程就会阻塞住,等待去消费新的任务。

3. 线程池都有哪些核心参数

主要就有四个参数,corePoolSizemaximumPoolSizekeepAliveTimequeue

光凭字面意思,其实很容易就能理解。

corePoolSize,就是核心线程数。也就是你的线程池里会存活这么多线程,线程不会死亡,会一直等待从内存队列中获取新的任务。

maximumPoolSize,就是最大线程数。也就是说你的线程池最多能创建多少个线程。

keepAliveTime,就是存活时间。也就是说,你除了核心的corePoolSize个线程外,其余创建出来的额外线程,空闲时最多存活多长时间。

queue,就是队列,你要使用的队列。可以是有界队列,也可以是无界队列。

4. 有界队列下的线程池的工作流程   

那如果你使用的是有界队列。比如说,你创建线程池的时候,有界队列设置的是最多存储500个任务。假如现在你的服务还没有处理完这些任务,corePoolSize线程都是忙碌状态,可是任务生产者又继续生产新的任务到队列中,如图

这个时候,就要看你的参数maximumPoolSize的值是不是大于corePoolSize了。比如你corePoolSize的值是5,maximumPoolSize是10。线程池就会创建额外的线程来处理新的任务。如图

   那如果任务生产者还在狂发消息,现在额外线程也无法创建了,那怎么办呢?

这个时候任务就只能被reject掉了。线程池会告诉你队列已经满了,新任务只能丢弃了,并抛出异常。

如果运行一段时间,内存队列中的任务都被消费完了,此时超过corePoolSize创建的额外线程就会处于空闲状态,超过keepAliveTime时间后就会自动释放了。

5. 无界队列下线程池可能带来的问题

那如果你使用的是无界队列,碰到上面的业务场景,假如任务生产者不停的往内存队列中放任务,而你的线程消费任务的速度比较慢,内存队列中积压了大量任务,会带来什么问题呢?

很明显,如果任务生产者一直往内存队列中放入任务,内存队列中积累的任务越来越多,队列就会越来越大,内存就会飙升起来,如果一直持续这样,甚至最终会导致你的系统发生OOM。

End

作者简介豪横的小耳朵一个豪横的程序员大家一起在技术的世界里豪横,用技术的眼光去看待世界。欢迎扫描下方二维码,持续关注,一大波原创系列文章正在路上

相关文章

  • 大白话聊聊线程池的工作原理和核心参数

    目录 1、为啥要使用线程池 2、线程池的工作原理 3、线程池都用哪些核心参数 4. 有界队列下的线程池的工作流程 ...

  • 线程池概述

    为什么要使用线程池? 线程池核心参数 线程池的几种拒绝策略 execute()和submit()的区别 线程池工作...

  • JAVA线程池常见用法

    JAVA线程池常见用法及其原理 1.JAVA线程池常见用法: 2.核心参数讲解 corePoolSize: 核心线...

  • 018 Android多线程-线程池

    前言 对于多线程,大家应该很熟悉。但是,大家了解线程池吗? 目录 1. 简介 2. 工作原理 2.1 核心参数 线...

  • 线程池工作机制与原理

    书接上文, Java线程池 。接下来记录一下线程池的工作机制和原理 线程池的两个核心队列: 线程等待池,即线程队列...

  • 线程池

    1、为什么要使用线程池2、线程池的工作原理3、线程池参数4、阻塞队列5、饱和策略6、向线程池提交任务7、线程池的状...

  • ThreadPool

    线程池核心参数 corePoolSize: int 核心线程数 线程池初始化后,线程池中没有任何线程,线程池会等待...

  • Android 中的线程池

    线程池核心参数 核心线程数 corePoolSize线程数容量 maximumPoolSize非核心线程被回收...

  • Java扫盲

    如何设计一个mq,jvm内存模型,动态代理原理,线程池核心参数,饱和策略,mybatis 原理;高可用如何实现; ...

  • 线程池核心参数

    线程池核心参数 1)corePoolSize(线程池基本大小) 2)maximumPoolSize(线程池最大数量...

网友评论

    本文标题:大白话聊聊线程池的工作原理和核心参数

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