谈谈你对线程池的理解?

简介: 今天和大家聊聊线程池。掌握线程池是后端程序员的基本要求。如果有哪里理解不正确,非常希望大家指出,接下来大家一起分析学习吧。

写在前面

今天和大家聊聊线程池。掌握线程池是后端程序员的基本要求。如果有哪里理解不正确,非常希望大家指出,接下来大家一起分析学习吧。

为什么要用线程池?

降低资源消耗。通过重复利用已创建的线程降低线程创建、销毁线程造成的消耗。

提高响应速度。当任务到达时,任务可以不需要等到线程创建就能立即执行。

提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配、调优和监控

线程池类参数详解

一、corePoolSize

核心线程数量,线程池维护线程的最少数量

二、maximumPoolSize

线程池维护线程的最大数量

三、keepAliveTime

线程池除核心线程外的其他线程的最长空闲时间,超过该时间的空闲线程会被销毁

四、unit

keepAliveTime的单位,TimeUnit中的几个静态属性:NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS

五、workQueue

线程池所使用的任务等待队列

六、threadFactory

线程工厂,用于创建线程,一般用默认的即可

七、handler

线程池对拒绝任务的处理策略

线程池的工作流程

一、submit ⼀个任务,判断当前的活跃线程数⼤⼩是否⼤于 corePoolSize,如果⼩于则使⽤threadFactory 新建⼀个线程来执⾏当前任务。

二、如果线程池当前的活跃线程数⼤于 corePoolSize,再判断当前 workQueue 是否已经满了,如果workQueue 没有满,则将任务加⼊的 workQueue 等待被执⾏。

三、如果 workQueue 已经满了,并且 maximumPoolSize ⼤于 corePoolSize,并且当前活跃线程数⼩于 maximumPoolSize,这个时候会新建⼀个线程执⾏任务。

四、如果当前活跃线程数⼤于 maximumPoolSize,则执⾏任务拒绝策略。

五、如果线程池中的线程数超过 corePoolsize,那么超过核⼼线程数的线程在空闲时间超过 keepAliveTime,会被关闭回收。

六、如果允许线程池核⼼线程超时,那么所有线程在空闲时间超过keepAliveTime时都会被关闭。

注意:

  1. 当 workQueue 使用的是无界限队列时,maximumPoolSize 参数就变的无意义了,比如 new LinkedBlockingQueue() 或者 new ArrayBlockingQueue(Integer.MAX_VALUE)。
  2. 使用 SynchronousQueue 队列时由于该队列没有容量的特性,所以不会对任务进行排队,如果线程池中没有空闲线程,会立即创建一个新线程来接收这个任务。maximumPoolSize 要设置大一点。
  3. 核心线程和最大线程数量相等时 keepAliveTime 无作用。

四种策略

1、AbortPolicy(被拒绝了抛出异常)

2、CallerRunsPolicy(使用调用者所在线程执行,就是哪里来的回哪里去)

3、DiscardOldestPolicy(尝试去竞争第一个,失败了也不抛异常)

4、DiscardPolicy(默默丢弃、不抛异常)

拒绝策略执行怎么办?

1、另外创建一个队列,当拒绝策略执行将任务放入队列。

通过定时任务去每隔一秒去查看线程池队列中是否有任务,没有则添加进去。

缺点: 任务会丢失,线程优雅关闭是指正常情况队列执行晚。会关闭,如果用这种方法创建则会丢失任务。

2、如果是特别重要的话就放入DB去持久化,给任务加个状态,通过状态来判断任务的执行情况。

3、其他情况要根据场景考虑比如又些任务过期淘汰。

总结

ThreadPoolExecutor 通过几个核心参数来定义不同类型的线程池,适用于不同的使用场景;其中在任务提交时,会依次判断corePoolSize, workQueque, 及maximumPoolSize,不同的状态不同的处理。技术领域水太深,如果不是日常使用,基本一段时间后某些知识点就忘的差不多了,因此阶段性地回顾与总结,对夯实自己的技术基础很有必要。

相关文章
|
7月前
|
Java 调度
Java并发编程:深入理解线程池的原理与实践
【4月更文挑战第6天】本文将深入探讨Java并发编程中的重要概念——线程池。我们将从线程池的基本原理入手,逐步解析其工作过程,以及如何在实际开发中合理使用线程池以提高程序性能。同时,我们还将关注线程池的一些高级特性,如自定义线程工厂、拒绝策略等,以帮助读者更好地掌握线程池的使用技巧。
|
3月前
|
存储 缓存 Java
JAVA并发编程系列(11)线程池底层原理架构剖析
本文详细解析了Java线程池的核心参数及其意义,包括核心线程数量(corePoolSize)、最大线程数量(maximumPoolSize)、线程空闲时间(keepAliveTime)、任务存储队列(workQueue)、线程工厂(threadFactory)及拒绝策略(handler)。此外,还介绍了四种常见的线程池:可缓存线程池(newCachedThreadPool)、定时调度线程池(newScheduledThreadPool)、单线程池(newSingleThreadExecutor)及固定长度线程池(newFixedThreadPool)。
|
7月前
|
监控 Java 调度
Java并发编程:线程池的原理与实践
【5月更文挑战第30天】 在现代软件开发中,尤其是Java应用中,并发编程是一个不可忽视的领域。线程池作为提升应用性能和资源利用率的关键技术之一,其正确使用和优化对系统稳定性和效率至关重要。本文将深入探讨线程池的核心原理、常见类型以及在实际开发中的使用案例,旨在帮助开发者更好地理解和运用线程池技术,构建高性能的Java应用程序。
|
6月前
|
监控 Java UED
Java并发编程:深入理解线程池的设计与应用
本文旨在通过数据导向和科学严谨的方式,深入探讨Java并发编程中的关键组件——线程池。文章首先概述了线程池的基本概念与重要性,随后详细解读了线程池的核心参数及其对性能的影响,并通过实验数据支持分析结果。此外,文中还将介绍如何根据不同的应用场景选择或设计合适的线程池,以及如何避免常见的并发问题。最后,通过案例研究,展示线程池在实际应用中的优化效果,为开发人员提供实践指导。
54 0
|
7月前
|
Java
线程池实践篇
线程池实践篇
26 0
|
7月前
|
Java
Java并发编程:线程池的深入理解与实践
【2月更文挑战第29天】在Java并发编程中,线程池是一种重要的技术手段,它可以有效地管理和控制线程,提高系统性能。本文将深入探讨线程池的原理,解析其关键参数,并通过实例演示如何在实际开发中合理使用线程池。
|
7月前
|
存储 SQL 编解码
面试必备的线程池知识-线程池的原理
面试必备的线程池知识-线程池的原理 线程池是一种多线程处理形式,它可以在执行大量短时间的任务时提高程序的性能和稳定性。线程池的核心思想是将需要执行的任务添加到线程池中,线程池会自动分配空闲线程来执行这些任务,当任务执行完毕后,线程会返回线程池中等待下一次任务的分配。
|
监控 Java 调度
JAVA线程池
想象一下,你是一个忙碌的领导,手头有一堆任务要完成。你一个人怎么可能同时完成这么多任务呢?于是乎,你决定雇佣一支“Java线程池服务团队”。 这个团队里有很多个“小伙伴”(线程),他们每个人都有各自的技能和专长。当你有新的任务时,你只需要把任务交给团队负责人(线程池)就好了。 团队负责人(线程池)会根据任务的复杂度和优先级,选择合适的小伙伴(线程)来处理任务。有些任务可能很简单,只需要一个小伙伴就能搞定;有些任务可能很复杂,需要几个小伙伴共同协作。 Java线程池是一种用于管理和复用线程的机制,它可以在需要执行任务时,从线程池中获取一个空闲线程来执行任务,而不是每次都创建新的线程。线程池可以提
57 0
|
Java 调度
|
设计模式 Java 调度
Java多线程案例之线程池
Java多线程案例之线程池
164 0
Java多线程案例之线程池