JUC八股:线程池及ThreadLocal

线程池

线程池原理及其七大核心参数含义

线程池的核心思路是:复用线程。避免了来一个任务就new,不需要就销毁的开销

流程:

任务来了,先判断当前线程数量是否小于corePoolSize

如果小于,则创建核心线程立即执行任务

如果核心线程数已满,则尝试将任务加入到阻塞队列

如果阻塞队列满了,就创建非核心线程执行任务;未满继续等待。

如果非核心线程数也达到最大,则触发拒绝策略

线程执行完毕后,或继续从阻塞队列中获取任务执行

非核心线程超过空闲时间keepAliveTime会被销毁

核心线程默认长期存活,不会销毁

简单概括就是:

优先使用核心线程

核心线程满后使用队列

队列满后扩容线程

达到最大线程数后拒绝执行任务

核心参数的实际含义

ThreadPoolExecutor的5个参数:核心线程数,最大线程数,阻塞队列,拒绝策略,空闲存活时间

  1. corePoolSize:核心线程数。即使这信啊线程空闲也不会被回收
  2. maximumPoolSize:最大线程数,线程池能创建线程的最大值。核心线程满了,队列满了才会创建
  3. keepAliveTime和unit:空闲线程的存活时间。超过核心线程的那部分,空闲时间超过就会被销毁
  4. workQueue:阻塞队列
  5. handler:拒绝策略,队列满了,线程也到顶了

线程池四大种类及特点

fixed :固定线程数线程池

特点:

  • 核心线程数固定
  • 最大线程数固定
  • 使用无界队列

适用场景

  • 稳定
  • 长期

cached :可缓存线程池

特点:

  • 核心线程数为0
  • 线程可无限扩容
  • 空闲线程会回收

适用场景:

  • 大量短时间异步任务
  • 突发并发场景

问题:线程数会无限增长

single :单线程线程池

特点:

  • 只有一个工作线程
  • 保证任务顺序
  • 适用无界队列

适用场景:

  • 顺序消费

schedule :定时线程池

特点:

  • 支持延迟任务
  • 支持周期任务
  • 基于DelayQueue

适用场景

  • 延迟执行
  • 周期执行

如何合理设置Java线程池的线程数

关键在于CPU密集型 还是I/O密集型 。

CPU密集型:线程数=CPU核心数+1

I/O密集型:线程数=CPU核心数*2

实际方法

  1. 先用上述公式跑起来
  2. 做压测;逐步加大并发,观察CPU利用率,平均响应时间,队列堆积数
  3. CPU占用率70%-80%健康。太低说明线程数可以加,太高说明瓶颈在CPU
  4. 观察队列堆积,如果队列经常满说明线程数不够或者下游扛不住

ThreadLocal原理

先看Thread的结构:

Thread

↓

ThreadLocalMap

↓

(ThreadLocal -> value)

回答要点:Thread内部维护了一个ThreadLocalMap,其中ThreadLocal就是key,线程私有数据作为value

实现:每个线程数据隔离

ThreadLocalMap 结构(内存泄露)

不是普通的HashMap

内部是:Entry\[\] table 数组结构

这导致了key是弱引用

作用:当hreadLocal 对象不用了,因为是弱引用,可以被GC(垃圾回收)。避免了key永远无法释放
问题:内存泄露

因为:key会被GC回收,但是value作为强引用不会被回收。导致value会一直挂在线程的ThreadLocalMap 里。导致内存泄露

解决方法:通常在finally中remove()

相关推荐
Java成神之路-5 分钟前
Java String 为什么不可变?和 HashMap 到底有什么关系?
java
hiahiahia1237 分钟前
Streaming Model Output
开发语言·前端
paopaokaka_luck8 分钟前
基于springboot+vue的益暖微光公益服务平台(DeepSeek公益助手、善款信息追溯、志愿服务积分闭环、ECharts运营分析、活动状态自动流转)
java·前端·javascript·spring boot·mysql·架构·echarts
文丑颜不良啊19 分钟前
LeetCode1401~1420题目解析
java·leetcode
Nuanyt21 分钟前
LeetCode Hot 100 链表专题2 3 题 (Java)
java·笔记·算法·leetcode·链表
文丑颜不良啊28 分钟前
LeetCode1341~1360题目解析
java·leetcode
熊猫钓鱼>_>34 分钟前
鸿蒙PC高分屏与键鼠交互适配:DPI缩放、右键菜单一次讲清
开发语言·笔记·华为·ai编程·harmonyos·鸿蒙·鸿蒙心迹
QianhangQianping1 小时前
撤销重做不是「存快照」:一个可视化编辑器的Operation 设计
java·前端·数据库·typescript·编辑器·前端架构·撤销重做
海绵宝宝转agent1 小时前
LeetCodehot100题解
java·笔记·学习·算法·leetcode·深度优先
SunnyDays10111 小时前
Java 操作 Word 脚注和尾注:添加、读取与删除
java·word