返回顶部
首页 > 资讯 > 精选 >使用Java无界队列的线程池会怎么样
  • 187
分享到

使用Java无界队列的线程池会怎么样

2023-06-04 08:06:40 187人浏览 八月长安
摘要

本篇内容主要讲解“使用Java无界队列的线程池会怎么样”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“使用Java无界队列的线程池会怎么样”吧!(1)背景引入今天跟大家聊一个互联网大厂的Java面

本篇内容主要讲解“使用Java无界队列的线程池会怎么样”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“使用Java无界队列的线程池会怎么样”吧!

(1)背景引入

今天跟大家聊一个互联网大厂的Java面试题:使用无界队列的线程池会导致内存飙升吗?

因为在面互联网大厂的时候,一定会问并发,问并发的时候一定会问到线程池,问到线程池一定会问构造线程池的一些参数的含义。

然后,有一些面试官会就线程池的具体场景,问一些可能会遇到的问题。

所以,在这里就可能有上述那样一个面试中的问题,算是Java面试里相对来说高阶一点的。

我相信大家一定起码知道线程池是个什么东西的。简单来说,就是维护一个池子,池子里面放了很多的线程。

然后来一个任务,某个线程就获取这个任务来执行,任务执行完之后线程是不会释放掉的,而是停留在线程池里继续等待下一个任务。

这样的一个好处是你没必要自己手动频繁的创建和销毁线程,毕竟线程是较重的资源,频繁的创建和销毁对系统性能是没好处的。

我们看看下面的图,回顾一下线程池的含义。

使用Java无界队列的线程池会怎么样

(2)线程池是如何构造的?

那么平时在Java里写代码的时候,大家记得不记得线程池是如何构造出来的呢?

是不是类似下面那样的代码,比如说我们构造一个线程数量固定的一个线程池:

使用Java无界队列的线程池会怎么样

那么Executors.newFixedThreadPool(10)内部到底又是如何构造出来线程池的呢?

其实很简单,翻开jdk源码就可以看到里面的代码如下:

使用Java无界队列的线程池会怎么样

简单来说,就是构造了一个ThreadPoolExecutor对象实例,你大致就认为他是一个线程池吧,传入了一些参数,这些参数大致包含了:

  1  ·   corePoolSize

  2  ·   maximumPoolSize

  3  ·   keepAliveTime

  4  · workQueue

假如说我们构造线程池传入的线程数量是10,那么在这里,corePoolSize和maximumSize都是10,keepAliveTime默认就是0,workQueue是一个无界的LinkedBlockingQueue。

接下来,我们具体来看看构造一个线程池传入一些参数之后,具体这个线程池的运行原理是什么。

(3)线程池的运行原理

简单来说,刚开始的时候其实线程池里是空的,就是一个线程都没有的,如下图所示。

使用Java无界队列的线程池会怎么样

接着如果你使用线程池提交一个任务进去,希望由线程池里的一个线程来执行,如下代码所示,就是提交一个任务:

使用Java无界队列的线程池会怎么样

这个时候,线程池会先看一下,现在池子里的线程数量有没有有达到corePoolSize指定的数量。

现在线程池里的线程数量是0,然后corePoolSize是10,那么肯定没达到了,所以直接会在线程池里创建一个线程出来然后执行这个任务,如下图。

使用Java无界队列的线程池会怎么样

接着假如说,这个线程处理完一个任务了,那么此时线程是不会被销毁的,他会一直等待下一个提交过来的任务。

那么,到底是怎么等待的呢?

很简单,线程池会搭配一个workQueue,比如这里搭配的就是一个无界的LinkedBlockingQueue,几乎可以无限量放入任务。

然后那个线程处理完一个任务之后,就会用阻塞的方式尝试从任务队列里获取任务,如果队列是空的,他就会阻塞卡在那儿不动,直到有人放一个任务到队列里,他才会获取到一个任务然后继续执行,循环往复,如下图。

使用Java无界队列的线程池会怎么样

接着再次提交任务,线程池一判断发现,诶?好像线程数量才只有1个,完全比corePoolSize(10个)要小,那么继续直接在池子里创建一个线程,然后处理这个任务,处理完了继续尝试从workQueue里阻塞式获取任务。

一直重复上面的操作,直到线程池里有10个线程了,达到了corePoolSize指定的数量,如下图。

使用Java无界队列的线程池会怎么样

这个时候你如果再提交任务,他一下子发现,诶?不对啊,线程池里已经有10个线程了,跟corePoolSize指定的线程数量一样了。

那么现在,我就不需要创建任何一个额外的线程了,现在你只要提交任务,全部直接入队到workQueue里就好。

此时线程池里的线程都阻塞式在workQueue上等待获取任务,有一个任务进来就会唤醒一个线程来处理这个任务,处理完了任务再次阻塞在workQueue上尝试获取下一个任务,如下图所示这个意思。

使用Java无界队列的线程池会怎么样

这里我们看到他用的是一个无界的LinkedBlockingQueue,但是假如说他用的是一个有界的队列呢?

比如说限定好了队列最多只能放10个任务,那么假如说,线程池里的线程来不及处理任务了,然后队列一下子放满了10个任务。

此时就会出现任务入队的失败,因为队列满了,无法入队。

然后就会尝试再次在线程池里创建线程,这个时候就会一直创建线程直到线程池里的线程数量达到maximumPoolSize指定的数量为止。

虽然这里fixed线程池默认corePoolSize和maximumPoolSize的数量都是一致的,但是可以假设此时maximumPoolSize的数量是20呢?

那么就会继续创建线程,直到线程数量达到20个,然后用额外创建的10个线程在队列满的情况下,继续处理任务。

整个过程,如下图所示:

使用Java无界队列的线程池会怎么样

接着万一队列满了,然后线程池的线程数量达到了maximumPoolSize指定的数量了,你额外创建线程都无法创建了,此时会如何呢?

答案是:会reject掉,不让你继续提交任务了,此时默认的就是抛出一个异常。

那么,在上图中额外创建出来的,超出corePoolSize的那些线程呢?

他们一旦创建出来之后,会发现线程池数量已经超过corePoolSize了,此时他们会尝试等待workQueue里的任务。

一旦超过keepAliveTime指定的时间,还获取不到任务,比如keepAliveTime是60秒,那么假如超过60秒获取不到任务,他就会自动释放掉了,这个线程就销毁了。

整个过程,如下图所示。

使用Java无界队列的线程池会怎么样

(4)无界队列引发的内存飙升

明白了线程池的运行原理了,这个面试题就好解答了。

我们以最常用的fixed线程池举例,他的线程池数量是固定的,因为他用的是近乎于无界的LinkedBlockingQueue,几乎可以无限制的放入任务到队列里。

所以只要线程池里的线程数量达到了corePoolSize指定的数量之后,接下来就维持这个固定数量的线程了。

然后,所有任务都会入队到workQueue里去,线程从workQueue获取任务来处理。

这个队列几乎永远不会满,当然这是几乎,因为LinkedBlockingQueue默认的最大任务数量是Integer.MAX_VALUE,非常大,近乎于可以理解为无限吧。

只要队列不满,就跟maximumPoolSize、keepAliveTime这些没关系了,因为不会创建超过corePoolSize数量的线程的。

同样,给大家来一张图,我们来看看:

使用Java无界队列的线程池会怎么样

那么此时万一每个线程获取到一个任务之后,他处理的时间特别特别的长,长到了令人发指的地步。比如处理一个任务要几个小时,此时会如何?

当然会出现workQueue里不断的积压越来越多得任务,不停的增加。

这个过程中会导致机器的内存使用不停的飙升,最后也许极端情况下就导致JVM OOM了,系统就挂掉了。

所以这就是这个面试题背后你要知道的线程池的运行原理,以及可能遇到的一些问题,大家要做到心里有数。

到此,相信大家对“使用Java无界队列的线程池会怎么样”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

--结束END--

本文标题: 使用Java无界队列的线程池会怎么样

本文链接: https://lsjlt.com/news/236994.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 使用Java无界队列的线程池会怎么样
    本篇内容主要讲解“使用Java无界队列的线程池会怎么样”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“使用Java无界队列的线程池会怎么样”吧!(1)背景引入今天跟大家聊一个互联网大厂的Java面...
    99+
    2023-06-04
  • Java线程池队列中的延迟队列DelayQueue怎么使用
    今天小编给大家分享一下Java线程池队列中的延迟队列DelayQueue怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧...
    99+
    2023-07-04
  • Java怎么自定义线程池中队列
    本篇内容介绍了“Java怎么自定义线程池中队列”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!背景业务交互的过程中涉及到了很多关于SFTP下载...
    99+
    2023-07-02
  • 详解Java线程池队列中的延迟队列DelayQueue
    目录DelayQueue延迟队列DelayQueue使用场景DelayQueue属性DelayQueue构造方法实现Delayed接口使用示例DelayQueue总结在阻塞队里中,除...
    99+
    2022-12-08
    Java延迟队列DelayQueue Java延迟队列 Java DelayQueue
  • SpringBoot线程池和Java线程池怎么使用
    这篇文章主要介绍“SpringBoot线程池和Java线程池怎么使用”,在日常操作中,相信很多人在SpringBoot线程池和Java线程池怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringB...
    99+
    2023-07-06
  • python线程池队列满了怎么解决
    当线程池的任务队列满了,有几种可能的解决方法: 增加队列的大小:可以通过调整线程池的任务队列的大小,来增加队列的容量。可以使用Th...
    99+
    2023-10-24
    python
  • java多线程队列的使用方法是什么
    在Java中,可以使用BlockingQueue来实现多线程队列。BlockingQueue是一个线程安全的队列,它提供了put()...
    99+
    2023-10-24
    java
  • 使用新的atomic.Pointer类型实现无锁无界队列
    php小编草莓今天要为大家介绍一种新的技术——使用新的atomic.Pointer类型实现无锁无界队列。在并发编程中,队列是一种常见的数据结构,但传统的队列实现通常需要使用锁来保证线程...
    99+
    2024-02-09
  • java怎么使用线程池启动多线程
    在 Java 中,可以使用线程池来启动多线程。以下是使用线程池启动多线程的示例代码:首先,需要导入 `java.util.concu...
    99+
    2023-09-15
    java
  • Java线程池怎么用
    小编给大家分享一下Java线程池怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、什么是线程池?线程池是一种用于实现计算机程序并发执行的软件设计模式。线程池...
    99+
    2023-06-15
  • Java并发之怎么使用线程池
    这篇文章主要介绍“Java并发之怎么使用线程池”,在日常操作中,相信很多人在Java并发之怎么使用线程池问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java并发之怎么使用线程池”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-16
  • Java线程池怎么使用AbortPolicy策略
    本篇内容介绍了“Java线程池怎么使用AbortPolicy策略”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!线程池ThreadPoolEx...
    99+
    2023-07-02
  • Springboot详解线程池与多线程及阻塞队列的应用详解
    目录一、案例场景二、使用类三、本例说明1.接收web请求2.后台任务处理3.关系说明四、代码1.OrderController2.FlowStarter流程启动器3.FlowMana...
    99+
    2024-04-02
  • JAVA基础:线程池的使用
    目录 1.概述 2.线程池的优势​​​​​​​ 2.1.线程池为什么使用自定义方式? 2.2.封装的线程池工具类有什么好处? 3.线程池的七大参数 3.线程池的创建 3.1. 固定数量的线程池 3.2. 带缓存的线程池 3.3. 执⾏定时任...
    99+
    2023-09-08
    java jvm 开发语言 多线程 线程池
  • java中的消息队列怎么利用多线程实现
    java中的消息队列怎么利用多线程实现?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。定义一个队列缓存池: //static修饰的成员变量和成员方法独立于该类的任何对象...
    99+
    2023-05-31
    java 多线程 ava
  • java线程池ThreadPoolExecutor类怎么用
    这篇文章将为大家详细讲解有关java线程池ThreadPoolExecutor类怎么用,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。在《阿里巴巴java开发手册》中指出了线程资源必须通过线程池提供,不允许...
    99+
    2023-06-29
  • 怎么在Java中使用线程工厂监控线程池
    这期内容当中小编将会给大家带来有关怎么在Java中使用线程工厂监控线程池,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。ThreadFactory线程池中的线程从哪里来呢?就是ThreadFoctorypu...
    99+
    2023-06-14
  • java怎么停止线程池中的线程
    要停止线程池中的线程,可以使用 `ExecutorService` 接口提供的 `shutdown()` 方法来停止线程池。这个方法...
    99+
    2023-08-20
    java
  • java的优先级队列怎么使用
    Java的优先级队列可以使用`java.util.PriorityQueue`类来实现。下面是一个使用优先级队列的示例:```jav...
    99+
    2023-09-07
    java
  • Java并发编程之LinkedBlockingQueue队列怎么使用
    这篇文章主要介绍了Java并发编程之LinkedBlockingQueue队列怎么使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Java并发编程之LinkedBlockingQueue队列怎么使用文章都会有...
    99+
    2023-06-30
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作