谈谈你对线程池的理解?

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

写在前面

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

为什么要用线程池?

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

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

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

线程池类参数详解

一、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,不同的状态不同的处理。技术领域水太深,如果不是日常使用,基本一段时间后某些知识点就忘的差不多了,因此阶段性地回顾与总结,对夯实自己的技术基础很有必要。

相关文章
|
1月前
|
Java 调度
Java并发编程:深入理解线程池的原理与实践
【4月更文挑战第6天】本文将深入探讨Java并发编程中的重要概念——线程池。我们将从线程池的基本原理入手,逐步解析其工作过程,以及如何在实际开发中合理使用线程池以提高程序性能。同时,我们还将关注线程池的一些高级特性,如自定义线程工厂、拒绝策略等,以帮助读者更好地掌握线程池的使用技巧。
|
2月前
|
Java
Java并发编程:线程池的深入理解与实践
【2月更文挑战第29天】在Java并发编程中,线程池是一种重要的技术手段,它可以有效地管理和控制线程,提高系统性能。本文将深入探讨线程池的原理,解析其关键参数,并通过实例演示如何在实际开发中合理使用线程池。
|
2月前
|
消息中间件 前端开发 NoSQL
面试官:说说线程池的工作原理?
面试官:说说线程池的工作原理?
34 0
|
5月前
|
存储 SQL 编解码
面试必备的线程池知识-线程池的原理
面试必备的线程池知识-线程池的原理 线程池是一种多线程处理形式,它可以在执行大量短时间的任务时提高程序的性能和稳定性。线程池的核心思想是将需要执行的任务添加到线程池中,线程池会自动分配空闲线程来执行这些任务,当任务执行完毕后,线程会返回线程池中等待下一次任务的分配。
|
6月前
|
存储 安全 Java
并发编程系列教程(07) - 线程池原理分析(一)
并发编程系列教程(07) - 线程池原理分析(一)
18 0
|
6月前
|
存储 缓存 监控
并发编程系列教程(08) - 线程池原理分析(二)
并发编程系列教程(08) - 线程池原理分析(二)
25 0
|
8月前
|
Java Spring
JAVA线程池相关原理
JAVA线程池相关原理
49 0
|
10月前
|
存储 SQL 监控
Java线程池实现原理详解
在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源。在Java中更是如此,虚拟机将试图跟踪每一个对象,以便能够在对象销毁后进行垃圾回收。所以提高服务程序效率的一个手段就是尽可能减少创建和销毁对象的次数,特别是一些很耗资源的对象创建和销毁。如何利用已有对象来服务就是一个需要解决的关键问题,其实这就是一些"池化资源"技术产生的原因
99 0
Java线程池实现原理详解
线程池:第一章:线程池的底层原理
线程池:第一章:线程池的底层原理
线程池:第一章:线程池的底层原理