新闻详情

新闻详情

首页 / 资讯中心 / 详情

AI全栈实战 | 1.7-02 并发基石:为什么禁止用 Executors 创建线程池?锁升级全过程拆解

发布时间:2026/11/14 9:31:44来源:尧图网络
AI全栈实战 | 1.7-02 并发基石:为什么禁止用 Executors 创建线程池?锁升级全过程拆解
上篇回顾1.7-01 把 JVM 内存模型、GC 算法、收集器演进、排查工具链一次讲透。本篇进入并发编程——这是 Java 高阶最硬核的部分也是线上事故的高发区。并发 bug 的特点是「本地测不出来、上线偶发出现、复现极难」根因往往是对 JMM、锁机制、线程池理解不到位。一、开篇一次诡异的线上死锁某团队线上服务每隔几小时就卡死重启后恢复。日志没有异常线程全部正常。运维用jstackdump 线程栈一看transfer-thread-1 prio5 BLOCKED - waiting to lock 0x000000076b4a0c80 - locked 0x000000076b4a0c90 transfer-thread-2 prio5 BLOCKED - waiting to lock 0x000000076b4a0c90 - locked 0x000000076b4a0c80经典死锁线程 1 持有锁 A 等锁 B线程 2 持有锁 B 等锁 A。根因是两个方法以相反顺序加锁——转账方法 A 先锁 from 再锁 to方法 B 先锁 to 再锁 from。修复方案统一锁顺序按 accountId 排序小的先锁。但这个 bug 在本地跑了 10 万次都没出现——并发问题的可怕在于概率性。本篇把 JMM、锁机制、线程池三大基石讲透让你写出不翻车的并发代码。二、JMMJava 内存模型2.1 为什么需要 JMMCPU 有多级缓存每个核心看到的变量值可能不一致。Java 为了跨平台统一行为定义了 JMM——规定线程何时能看到其他线程的修改。线程 1 线程 2 ↓ ↓ 工作内存 工作内存 ↕ ↕ └───── 主内存 ───────┘JMM 规定线程不能直接操作主内存必须先读到工作内存修改后写回。2.2 三大特性特性含义保证手段原子性操作不可分割synchronized / Lock / AtomicInteger可见性修改后其他线程立即可见volatile / synchronized / final有序性防止指令重排volatile / happens-before2.3 volatile 的语义边界volatile 做两件事可见性写后立刻刷主内存读前从主内存刷新2禁止指令重排插入内存屏障volatile不保证原子性。i即使 i 是 volatile 也不是线程安全的——i是「读加写」三步中间可能被打断。// volatile 的正确用法状态标志privatevolatilebooleanrunningtrue;publicvoidstop(){runningfalse;}publicvoidrun(){while(running){// 工作循环}}2.4 happens-before 规则happens-before 是 JMM 的核心——如果 A happens-before B那么 A 的操作对 B 可见。规则说明程序顺序同一线程内前操作 happens-before 后操作锁规则unlock happens-before 后续 lockvolatile 规则volatile 写 happens-before 后续 volatile 读线程启动start() happens-before 线程内任意操作线程终止线程内操作 happens-before 其他线程检测到终止传递性A→B 且 B→C 则 A→C三、synchronized 锁升级全过程JDK 6 后 synchronized 不再是「重量级锁」一棍子打死而是根据竞争情况自动升级。无锁 → 偏向锁 → 轻量级锁 → 重量级锁3.1 偏向锁第一个线程访问时对象头记录该线程 ID。下次该线程进入不需要 CAS 操作直接进入。适合单线程反复进入同步块的场景。3.2 轻量级锁第二个线程来竞争时偏向锁撤销升级为轻量级锁。用 CAS 操作把对象头指向线程栈中的锁记录。适合交替执行、无真实竞争的场景。3.3 重量级锁CAS 自旋超过阈值默认 10 次仍没拿到锁升级为重量级锁——进入 monitor线程挂起等待。适合竞争激烈的场景。3.4 锁升级不可逆一旦升级到重量级锁就不会降级。所以不要在低竞争场景用 synchronized 反复触发升级。3.5 synchronized vs ReentrantLock维度synchronizedReentrantLock实现JVM 内置java.util.concurrent 类锁释放自动手动 unlock必须 finally可中断不可lockInterruptibly()超时不可tryLock(timeout)公平锁非公平可配公平/非公平条件变量1 个wait/notify多个 Condition推荐简单场景用 synchronized语法简洁、不会忘记 unlock复杂场景超时、中断、多条件用 ReentrantLock。四、AQSJUC 的核心框架AbstractQueuedSynchronizer 是 ReentrantLock、CountDownLatch、Semaphore、CyclicBarrier 的底层框架。4.1 核心思想1. state 变量表示同步状态volatile int 2. CLH 队列管理等待线程 3. 模板方法模式子类实现 tryAcquire/tryRelease4.2 CLH 队列head → [线程1] ⇄ [线程2] ⇄ [线程3] ← tail ↑ 已获取锁 ↑ 自旋等待 ↑ 自旋等待等待线程在队列里自旋轻量级锁阶段或挂起重量级锁阶段前驱节点释放后唤醒后继。4.3 ReentrantLock 的 tryAcquire// 简化版finalbooleannonfairTryAcquire(intacquires){finalThreadcurrentThread.currentThread();intcgetState();if(c0){// 无锁状态CAS 抢锁if(compareAndSetState(0,acquires)){setExclusiveOwnerThread(current);returntrue;}}elseif(currentgetExclusiveOwnerThread()){// 重入state 加 1setState(cacquires);returntrue;}returnfalse;}五、CAS 与 ABA 问题5.1 CAS 原理Compare And Swap比较当前值是否等于预期值相等则更新为新值。是乐观锁的核心。AtomicIntegerainewAtomicInteger(0);ai.compareAndSet(0,1);// 预期0更新为1 → trueai.compareAndSet(0,2);// 预期0但已是1 → false5.2 ABA 问题线程1 读到值 A 线程2 把 A 改成 B又改回 A 线程1 CAS(A→C) 成功值虽然还是 A但中间已经被改过。对纯数值无影响对引用类型可能有问题对象字段被改了但引用没变。5.3 解决方案AtomicStampedReference给值加版本号CAS 时同时比较值和版本号。AtomicStampedReferenceIntegerrefnewAtomicStampedReference(100,0);// 初始值100版本0int[]stampnewint[1];Integervalref.get(stamp);// val100, stamp[0]0ref.compareAndSet(100,200,0,1);// 预期值100版本0 → 更新为200版本1六、线程池为什么阿里禁止 Executors6.1 Executors 的隐患// 阿里规约禁止这两种Executors.newFixedThreadPool(10);// 队列 LinkedBlockingQueue 无上限 → OOMExecutors.newCachedThreadPool();// 线程数 Integer.MAX_VALUE → OOMnewFixedThreadPool 的队列是LinkedBlockingQueue无界任务堆积导致 OOM。newCachedThreadPool 的最大线程数是Integer.MAX_VALUE创建过多线程导致 OOM。6.2 正确做法手动配置 ThreadPoolExecutorThreadPoolExecutorexecutornewThreadPoolExecutor(corePoolSize,// 核心线程数maxPoolSize,// 最大线程数keepAliveTime,// 空闲存活时间TimeUnit.SECONDS,newArrayBlockingQueue(1000),// 有界队列newThreadFactoryBuilder().setNameFormat(biz-pool-%d).build(),// 命名便于排查newThreadPoolExecutor.CallerRunsPolicy()// 拒绝策略);6.3 七参数详解参数说明corePoolSize常驻线程数maxPoolSize队列满后扩到的最大线程数keepAliveTime非核心线程空闲存活时间unit时间单位workQueue任务队列threadFactory线程工厂命名很重要handler拒绝策略6.4 线程数设置公式CPU 密集型计算为主线程数 CPU 核数 1IO 密集型网络/DB/文件为主线程数 CPU 核数 * (1 IO等待时间/CPU时间)经验值IO 密集型通常 2~10 倍 CPU 核数。具体靠压测调。6.5 四种拒绝策略策略行为适用场景AbortPolicy抛 RejectedExecutionException默认要求严格CallerRunsPolicy由提交线程执行不丢任务、降级DiscardPolicy静默丢弃可容忍丢任务DiscardOldestPolicy丢最早未处理任务最新优先生产推荐CallerRunsPolicy——不丢任务用提交线程做背压。七、CompletableFuture现代异步编程CompletableFutureOrderfutureCompletableFuture.supplyAsync(()-userService.getById(userId),executor).thenApply(user-{OrderordernewOrder(user);returnorder;}).thenCombine(CompletableFuture.supplyAsync(()-couponService.get(userId),executor),(order,coupon)-{order.setCoupon(coupon);returnorder;}).exceptionally(ex-{log.error(创建订单失败,ex);returnOrder.failed(ex.getMessage());});Orderorderfuture.get(3,TimeUnit.SECONDS);优势链式编排、超时控制、异常处理、多任务组合。比 Future 灵活得多。八、小结表模块关键点易踩坑JMM可见性/原子性/有序性volatile 不保证原子性synchronized锁升级不可逆低竞争反复触发升级AQSstate CLH 队列自旋过多浪费 CPUCAS乐观锁ABA 问题线程池手动配七参数Executors 无界队列 OOMCompletableFuture异步编排必须传自定义线程池
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

【外设】之大彩串口显示屏 2026/11/14 3:51:47

【外设】之大彩串口显示屏

大彩串口屏初步使用 1 .官网下载 STM32 屏幕 GUI 设计资料 http://www.gz-dc.com/category/typeid/4112 找到 STM32 Keil 工程,移植相关代码因项目而异进行移植,由于项目简单,本人只对用到的指令接口进行修改。 比如:注意事项&…

阅读更多 →
无法下载Windows系统iso文件 2026/11/12 23:59:09

无法下载Windows系统iso文件

当我遇到这个问题的时候,我打开了一个网站: 登录 然后我打算下载的时候: 突然那个官方的连接就可以下载了:

阅读更多 →
【清华代码熊】DeepSeek V4.1 Flash 后训练详解 2026/11/13 10:09:00

【清华代码熊】DeepSeek V4.1 Flash 后训练详解

📌 上期解析了 DeepSeek V4.1 Flash 模型架构改进,本期解析 DeepSeek V4.1 Flash 预训练/后训练技术: 🌟 预训练:45T 文本 多模态混合语料、直接训练 sparse attention(取消 DeepSeek V4 的 dense 冷启动&…

阅读更多 →
Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ... 2026/11/13 13:31:48

Shuffle-R1: Efficient RL framework for Multimodal Large Language Models via Data-centric Dynamic ...

文章主要内容和创新点 主要内容 本文聚焦于多模态大语言模型(MLLM)强化学习(RL)训练中的效率问题,提出了一个名为Shuffle-R1的框架。研究发现,当前RL训练存在两个关键缺陷: 优势值坍缩(Advantage Collapsing):批次中大多数优势值集中在零附近,导致有效梯度信号被淹…

阅读更多 →
PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction 2026/11/13 16:11:45

PRvL: Quantifying the Capabilities and Risks of Large Language Models for PII Redaction

一、文章主要内容总结 本文聚焦于利用大型语言模型(LLMs)实现个人身份信息(PII)脱敏的研究,旨在解决传统脱敏方法(如基于规则的系统、领域特定命名实体识别(NER)模型)泛化能力差、跨格式/跨语境适应性弱的问题。 研究通过全面评估多种LLM架构(包括密集型LLM(D-LLM…

阅读更多 →
LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model 2026/11/14 3:51:43

LLaVA-RE: Binary Image-Text Relevancy Evaluation with Multimodal Large Language Model

文章主要内容和创新点 主要内容 本文聚焦于二进制图像-文本相关性评估任务(判断图像与文本“相关”或“不相关”),针对该任务中文本格式多样、相关性定义随场景变化等挑战,提出了基于多模态大语言模型(MLLM)的解决方案LLaVA-RE。 模型设计:LLaVA-RE基于LLaVA 1.5架构,…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉