iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Java并发之怎么使用线程池
  • 198
分享到

Java并发之怎么使用线程池

2023-06-16 05:06:49 198人浏览 薄情痞子
摘要

这篇文章主要介绍“java并发之怎么使用线程池”,在日常操作中,相信很多人在Java并发之怎么使用线程池问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java并发之怎么使用线程池”的疑惑有所帮助!接下来,请跟

这篇文章主要介绍“java并发之怎么使用线程池”,在日常操作中,相信很多人在Java并发之怎么使用线程池问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java并发之怎么使用线程池”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

线程池的作用

池化技术是一种很常见的计算机技术,主要是为了复用和提高性能,如内存池、连接池、对象池等。线程池也不例外,他的主要作用如下:

  • 提高性能:线程的频繁创建和销毁会产生的很大的系统开销,线程池中的线程复用可以大幅度的减少这种不必要的开销。

  • 复用和管理:方便对池子中的线程进行管理和复用,避免在生产环境中大量的创建线程。

  • 解耦:只暴露提交任务的接口,将线程池的创建、销毁等工作与业务解耦。

jdk 在并发包中为我们定义了一套 Executor 框架,帮助开发人员有效地进行线程控制,有基础的线程池类、有线程池工厂,但是最最重要还是  ThreaPoolExecutor,也是面试中最常问的知识点。本文重点介绍 ThreaPoolExecutor 的原理。

线程池的参数说明

ThreaPoolExecutor(     int corePoolSize,     long keepAliveTime,     TimeUnit unit,     BlockingQueue<Runnable> workQueue,     ThreadFactory threadFactory,     RejectedExecutionHandler handler) )

ThreaPoolExecutor 参数的含义如下

  • corePoolSize: 线程池中核心线程的数量。

  • maximumPoolSize: 线程池中的最大线程数量。

  • keepAliveTime: 当线程池数量超过 corePoolSize 时,多余的空闲线程的存活时间。即超过 coolPoolSize 的空闲线程在  多长时间内,会被销毁。

  • unit: keepAliveTime 的单位,可以为 时、分、秒等多种值。

  • workQueue: 任务队列,存放被提交但尚未被执行的任务。

  • threadFactory: 线程工厂,用于创建线程,一般用默认即可。

  • handler: 拒绝策略,当线程池处理不过来任务时,如何拒绝任务。

以上参数中 workQueue、threadFactory、handler 相对复杂,需要单独介绍,下面主要介绍下 ThreadFactory 和 RejectedExecutionHandler

1. 线程工厂:ThreadFactory

线程池中的线程都由 TrheadFactory 定义的线程工厂来创建,它是一个接口只有 Thread newThread(Runnable r)  方法,用来创建线程。虽然创建 ThreadPoolExecutor 的时候可以不指定该参数,但是阿里巴巴编码规约建议最好指定该参数,有以下几个好处:

  • 跟踪线程池在何时、创建了多少线程。

  • 可以自定义线程池的名称、组以及优先级等信息。

  • 设置线程的其他状态等,如守护进程。

2. 拒绝策略:RejectedExecutionHandler

当线程池线程数量达到 maxPoolSize 大小时,再提交新的任务会执行拒绝策略,JDK 定义了四种拒绝策略:

  • AbortPolicy 该策略直接抛出异常

  • CallerRunsPolicy  调用者线程处理任务,该策略并不是真正的丢弃任务,会让当前线程来执行被抛弃的任务,由于只有一个线程,所有的任务会被串行执行。

  • DiscardOldestPolicy 丢弃最老的一个请求,即队列头部的即将被执行的任务,并尝试再次提交当前任务。

  • DiscardPolicy 该策略默默丢弃无法处理的任务。

以上四种拒绝策略都继承了接口 RejectedExecutionHandler 并实现该接口的 rejectedExecution(Runnable r,  ThreadPoolExecutor executor) 方法。如果以上四种拒绝策略都满足不了你的需求,可以自定义拒绝策略,继承接口  RejectedExecutionHandler 并实现方法即可。

线程池的调度逻辑

ThreaPoolExecutor 对提交的任务处理逻辑如下图,

Java并发之怎么使用线程池

1. 提交任务时:

  • 如果线程池中的线程数小于 corePoolSize (无论是否有空闲线程),创建新的线程(谓之核心线程)来处理。

  • 如果线程池中的线程数已经大于或者 corePoolSize ,新提交的任务将被放置到等候队列中,等待调度。

  • 如果等待队列已满,并且线程池中的线程数量小于 maxPoolSize,将继续创建新线程处理任务。

  • 如果队列已满且线程数量也达到了上限,将使用拒绝策略来处理。

2. 任务进行中时:

当队列中的任务已经执行完,部分线程开始空闲,非核心线程会在空闲后的 keepAliveTime 的时间内自行销毁。

而空闲核心线程是否退出取决于线程池的另一个参数 allowCoreThreadTimeOut 。当配置为 true  的时候,即使是核心线程,超时也会退出。

线程池的生命周期

线程池同线程一样也有自己的生命周期,包括 RUNNING、SHUTDOWN、STOP、TIDYING 和 TERMINATED  五种状态,他们的转换关系如下图,并且这些转换时不可逆的。

Java并发之怎么使用线程池

1. RUNNING

该状态是线程池的工作状态,能够接受新任务以及对接受的任务进行处理。线程池的初始状态,即线程创建成功后就处理此状态。

2. SHUTDOWN

关闭状态,线程池不再接受新的任务,但是能继续处理提交到线程池中的任务。线程状态 RUNNING 的情况下调用 shutdown()  方法进入该状态。

3. STOP

停止状态,线程池不接受新的任务,也不处理阻塞队列中的任务,同时会中断正在执行任务的线程。在线程处于 RUNNING 或者 SHUTDOWN 状态下调用  shutdownNow() 方法进入该状态。

4. TIDYING

所有任务都销毁了,workCount 为 0,会自动从 RUNNING 或者 STOP 状态转化为 TIDYING 状态。在转换过程中会调用  terminated() 方法,ThreadPoolExecutor 类的 ternimated() 方法为空,如果想在线程池变成 TIDYING  的时候有所处理,可以重载该方法。

线程池在 SHUTDOWN 状态下,阻塞队列为空并且执行任务为空时转换为 TIDYING 状态;线程池在 STOP 状态下,执行的任务为空时转换为  TIDYING 状态。

5. TERMINATED

结束状态,线程池的最终状态,该状态的线程池不会再有任何操作。线程池执行 terminated() 方法后处于该状态。

JDK 四种线程池

了解 ThreaPoolExecutor 的基本原理后再来看看 JDK 在 Executors 中为开发人员定义的四个线程池工厂方法,其实它们内部调用的是  ThreaPoolExecutor,只是使用了不同的参数,下面来了解下它们的特性。

newFixedThreadPool()  方法:该方法返回一个固定线程池数量的线程,提交任务时如果线程池中有空闲线程,则立即执行,没有则新的任务会被缓存在一个任务队列中,它创建线程池的代码如下:

public static ExecutorService newFixedThreadPool(int nthread) {   return new ThreadPoolExecutor(nthread,                                  nthread,                                  0L,                                  TimeUnit.MILLSECCONDS,                                  new LikedBlockingQueue<Runnable>()) }

newSingleThreadExecutor()  方法:该方法返回只有一个线程的线程池,如果多余的任务提交到线程池,则被提交到任务队列中。它创建线程池代码如下:

public static ExecutorService newSingleThreadExecutor() {   return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1,                                                                          1,                                                                         0L, TimeUnit.MILLISECONDS,                                                                         new LinkedBlockingQueue<Runnable>())); }

newCachedThreadPool() 方法:该方法返回一个可根据实际情况调整线程数的线程池,它的核心线程数为 0 ,线程总数为  Integer.MAX_VALUE ,队列采用的是 SynchronousQueue,这样即使线程满,任务也不能提交到队列中。

public static ExecutorService newCachedThreadPool() {         return new ThreadPoolExecutor(0, Integer.MAX_VALUE,                                       60L, TimeUnit.SECONDS,                                       new SynchronousQueue<Runnable>());     }

newScheduledThreadPool():该方法一个固定长度的线程池,并且以延迟或者定时的方式去执行任务。它的队列使用  DelayedWorkQueue,所以任务必须继承 Delay 接口。

public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {     return new ScheduledThreadPoolExecutor(corePoolSize); }  public ScheduledThreadPoolExecutor(int corePoolSize) {     super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS,           new DelayedWorkQueue()); }

到此,关于“Java并发之怎么使用线程池”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

--结束END--

本文标题: Java并发之怎么使用线程池

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

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

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java并发之怎么使用线程池
    这篇文章主要介绍“Java并发之怎么使用线程池”,在日常操作中,相信很多人在Java并发之怎么使用线程池问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Java并发之怎么使用线程池”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-16
  • Java并发编程面试之线程池
    目录什么是线程池线程池好处线程池的执行流程怎么用线程池corePoolSizemaximumPoolSizekeepAliveTimeunitworkQueuethreadFacto...
    99+
    2022-11-12
  • 怎么在Java并发包中使用ThreadPoolExecutor线程池
    这篇文章给大家介绍怎么在Java并发包中使用ThreadPoolExecutor线程池,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。一、线程池简介线程池的使用主要是解决两个问题:①当执行大量异步任务的时候线程池能够提供...
    99+
    2023-06-15
  • Python并发编程之线程池/进程池
    原文来自开源中国前言python标准库提供线程和多处理模块来编写相应的多线程/多进程代码,但当项目达到一定规模时,频繁地创建/销毁进程或线程是非常消耗资源的,此时我们必须编写自己的线程池/进程池来交换时间空间。但是从Python3.2开始,...
    99+
    2023-06-02
  • java怎么自定义并发线程池
    要自定义并发线程池,可以使用`ThreadPoolExecutor`类来实现。`ThreadPoolExecutor`是`Execu...
    99+
    2023-10-25
    java
  • Java并发编程之线程池的示例分析
    这篇文章将为大家详细讲解有关Java并发编程之线程池的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。什么是线程池是一种基于池化思想管理线程的工具。池化技术:池化技术简单点来说,就是提前保存大量的资...
    99+
    2023-06-20
  • Java手写线程池之向JDK线程池进发
    目录前言JDK线程池一瞥自己动手实现线程池线程池参数介绍实现Runnable实现Callable拒绝策略的实现线程池关闭实现工作线程的工作实现线程池实现的BUG完整代码线程池测试总结...
    99+
    2022-11-13
    Java手写线程池 Java线程池
  • SpringBoot线程池和Java线程池怎么使用
    这篇文章主要介绍“SpringBoot线程池和Java线程池怎么使用”,在日常操作中,相信很多人在SpringBoot线程池和Java线程池怎么使用问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SpringB...
    99+
    2023-07-06
  • Java并发编程之线程怎么创建
    本篇内容主要讲解“Java并发编程之线程怎么创建”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Java并发编程之线程怎么创建”吧!1.线程与进程进程是代码在数据集合上的一次运行活动,是系统进行资...
    99+
    2023-06-30
  • 在java项目中使用线程池实现并发编程
    今天就跟大家聊聊有关在java项目中使用线程池实现并发编程,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。一、任务和执行策略之间的隐性耦合Executor可以将任务的提交和任务的执行策...
    99+
    2023-05-31
    java 线程池 并发编程
  • Java多线程并发之ReentrantLock
    目录ReentrantLock公平锁和非公平锁重入锁小结疑惑ReentrantLock 公平锁和非公平锁 这个类是接口 Lock的实现类,也是悲观锁的一种,但是它提供了 lock和 ...
    99+
    2023-05-18
    Java 多线程并发 Java ReentrantLock
  • Java并发包线程池ThreadPoolExecutor的实现
    线程池主要解决两个问题:一是当执行大量异步任务时线程池能够提供较好的性能。在不使用线程池时,每当需要执行异步任务时直接new一个线程来运行,而线程的创建和销毁都是需要开销的。线程池里...
    99+
    2022-11-13
  • 详解Java并发包中线程池ThreadPoolExecutor
    目录一、线程池简介二、ThreadPoolExecutor类2.1、ThreadPoolExecutor成员变量以含义2.2、ThreadPoolExecutor的参数以及实现原理2...
    99+
    2022-11-12
  • Java多线程并发ReentrantLock怎么使用
    这篇文章主要介绍“Java多线程并发ReentrantLock怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“Java多线程并发ReentrantLock怎么使用”文章能帮助大家解决问题。背景...
    99+
    2023-07-02
  • Java多线程并发AbstractQueuedSynchronizer怎么使用
    这篇文章主要介绍“Java多线程并发AbstractQueuedSynchronizer怎么使用”,在日常操作中,相信很多人在Java多线程并发AbstractQueuedSynchronizer怎么使用问题上存在疑惑,小编查阅了各式资料,...
    99+
    2023-07-02
  • Java线程池怎么用
    小编给大家分享一下Java线程池怎么用,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!一、什么是线程池?线程池是一种用于实现计算机程序并发执行的软件设计模式。线程池...
    99+
    2023-06-15
  • 解密TaurusDB存储端高并发之线程池
    图1 TaurusDB整体架构 图2 slice功能组件 从图2可知,TaurusDB的存储层,不单单只做存储相关的工作,也需要大量的算力,比如consolidation生成特定数据页、compation回收旧版本数据、Buff...
    99+
    2020-11-07
    解密TaurusDB存储端高并发之线程池
  • java怎么使用线程池启动多线程
    在 Java 中,可以使用线程池来启动多线程。以下是使用线程池启动多线程的示例代码:首先,需要导入 `java.util.concu...
    99+
    2023-09-15
    java
  • Java并发线程池实例分析讲解
    目录一.为什么要用线程池二.线程池的好处三.原理解析四.4种线程池五.线程池处理流程六.源码分析一.为什么要用线程池 先来看个简单的例子 1.直接new Thread的情况: ...
    99+
    2023-02-02
    Java并发线程池 Java线程池
  • Java并发编程之线程中断
    目录线程中断: void interrupted()方法:中断线程,例如,当线程A运行时,线程B可以调用线程A的interrupted()方法来设置线程的中断标志为true并立即返回...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作