ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Java-volatile可见性-为什么改了标志位线程却读不到

Java-volatile可见性-为什么改了标志位线程却读不到 Java volatile 可见性为什么改了标志位线程却读不到主线程改了boolean标志工作线程却读不到本质是 volatile 缺失导致的可见性问题。本文讲清楚 JMM 工作内存/主内存模型、volatile 的可见性与有序性以及它不保证原子性的边界。一、问题案例一个后台任务用boolean标志控制退出主线程把标志设成false工作线程的while循环却一直退不出来。classWorkerimplementsRunnable{privatebooleanrunningtrue;// ❌ 没加 volatilepublicvoidrun(){while(running){/* 干活 */}}publicvoidstop(){runningfalse;}}二、原理详解JMM 与可见性Java 内存模型JMM里每个线程有自己的工作内存高速缓存共享变量在主内存。running没加 volatile → 工作线程可能把它缓存进自己的工作内存主线程调stop()改的是主内存的值工作线程读的是自己工作内存的旧值 → 永远看不到变化。volatile干两件事保证可见性每次读写都直连主内存改了就立刻能被别的线程看到禁止指令重排保证写读顺序防止拿到「半初始化」的对象。但 volatile 不保证原子性。i这种「读-改-写」复合操作多线程下依然会丢更新。三、实战代码privatevolatilebooleanrunningtrue;一行搞定标志位可见性问题。四、常见踩坑i不是原子的要用AtomicInteger或锁。双重检查锁DCL单例要加 volatileinstance new Xxx()不是原子操作可能发生指令重排导致别的线程拿到未初始化完的对象instance加 volatile 可以禁止这种重排。五、总结多线程共享的标志位加 volatile。volatile 保证可见性 有序性不保证原子性。复合操作i、check-then-act交给AtomicX或锁。我是无羡小剑全栈偏后端的独立开发者。作品集无羡 · 独立开发者作品集如果对你有帮助欢迎点赞、收藏、关注。
返回列表