编程 5 年之惑,AI 给出完美答案

前言

今年都还没写过一个需求呢😣,闲来无事,突发奇想 volatile 可见性的问题,我以前一直都没模拟成功过呢。现在AI这么厉害,应该能帮我解决这个困惑吧!!!

volatile变量的修改,能立即对其他线程可见(强制刷新主内存和本地缓存)。

相信所有的java🧔对这句话非常的熟悉了。有多少个人去做过测试,我3、5年前就已经去做过测试了。但是很遗憾,当时怎么也复现不了。不管我用不volatile 效果都一样呢。今天AI 帮我解决了我的困惑!!!

🎈不想看过程的,直接看总结吧!

可见性理论测试

错误的测试案例

下面是我做的测试代码,没有用volatile修饰,所以理论上来说一直会输出Worker thread running...

实现代码:

java 复制代码
public class Test {
    private static boolean stop = false;

    public static void main(String[] args) {
        Thread workerThread = new Thread(() -> {
            int count = 0;
            // 按照没有用volatile修饰,当前线程不能看到变量被修改,所以理论上来说不会退出循环
            while (!stop) {
                System.out.println("Worker thread running...");
                count++;
            }
            System.out.println("Worker thread stopped, count: " + count);
        });

        workerThread.start();

        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        stop = true;
        System.out.println("Main thread set stop to true");
    }

}

执行结果

text 复制代码
Worker thread running...
Main thread set stop to true
Worker thread stopped, count: 1

竟然和想象中的完全不一样。

有大佬看到这儿已经定位到了问题了么❔

AI解惑

为什么我不用volatile修饰 其他线程也能看到变化呢

就是说在某些情况下会去与主存同步,获取最新值。下面列举了比如CPU混存满了,或者到了特定的时间间隔。

如果是因为这两个原因,就有点说不通了,我就运行一个demo,而且每次执行都是同样的结果。

没有获取到我想要的答案,那就继续AI吧✈

能帮我举一个 未用volatile修饰变量,其他线程看不到变量变化的

  • 看一下AI是怎么解释的吧,如下图:*

运行上面的代码,确实出现 无法对出循环的问题。 这个例子和我开篇的例子就 少了一个System.out.println("Worker thread running...");

🤩看到这儿 ,应该❗大概❗好像❗感觉❗知道问题所在了吧❓

我的猜测

可能是System.out.println()加了锁的,导致线程的工作内存被刷新了。 点进去看果然sout(打印方法简称)方法是加了锁的。

java 复制代码
public void println(String x) {
    if (getClass() == PrintStream.class) {
        //也加了锁的
        writeln(String.valueOf(x));
    } else {
        synchronized (this) {
            print(x);
            newLine();
        }
    }
}

继续问AI,看看AI是怎么解释的

为什么用了sout,循环就会退出(没有用volatile,其他线程也能看到修改)

看一下AI是怎么解释的吧,如下图:

测试结论

在lock、sync修饰的代码,工作内存的变量会被刷新。所有我们在 打印 没有用volatile 修饰的变量的时候,变量也会被刷新,导致测试结果偏离预期

Tips:用在while 循环中使用Thread.sleep() 也会退出循环,是不是也意味着它也能刷线程的工作内存呢?

目前作者也是没有找到比较官方的资料

总结

本篇文章利用AI 分析了 无法复现普通变量 的不可见性 的原因。最后确认是因为使用sout访问变量,sout底层加锁,所以变量在工作内存中被刷新了,导致程序员的运行结果和理论上的不一致。

原来小小sout竟然有这么大的能量😱,兄弟们好好的把日志打印给我用起来,防御式编程✈啊,让后面的同学删除一行日志,就导致运行结果就变了,这不美滋滋。

最后,想了解volatile更多的知识的 ,推荐阅读:深入解析Java中volatile关键字的底层原理

相关推荐
轻刀快马23 分钟前
跨越软硬件的共鸣(二):从 Cache 写策略看 Redis 与 DB 的一致性博弈
java·开发语言·redis·计算机组成原理
折哥的程序人生 · 物流技术专研23 分钟前
Java 23 种设计模式:从踩坑到精通 | 装饰器模式 —— 比继承更灵活的扩展方式,你用过吗?
java·装饰器模式·java面试·结构型模式·java设计模式·javaio·从踩坑到精通
lili001231 分钟前
2026 企业 AI 选型新范式:OpenRouter Fusion 证明多模型融合性价比远超单模型,企业该如何重构技术栈? - 微元算力(weytoken)
java·人工智能·python·重构·ai编程
shushangyun_33 分钟前
汽车服务行业B2B平台+AI解决方案哪家专业:2026年最新测评
java·运维·网络·数据库·人工智能·汽车
A.说学逗唱的Coke36 分钟前
【大模型专题】Spring AI Alibaba × Skill 整合实战:让 AI 真正“会干活
java·人工智能·spring
大黄说说1 小时前
深入理解 Go 协程 Goroutine:并发编程的核心精髓
java·数据库·python
许彰午1 小时前
38_Java设计模式之装饰器模式
java·设计模式·装饰器模式
折哥的程序人生 · 物流技术专研1 小时前
Java 23 种设计模式:从踩坑到精通 | 组合模式 —— 树形结构处理,部分与整体一视同仁
java·组合模式·java面试·springsecurity·结构型模式·java设计模式·从踩坑到精通
郝学胜-神的一滴1 小时前
完全二叉树与堆底层原理深度剖析 | 手写C++大顶堆实现
java·开发语言·数据结构·c++·python·算法
农民小飞侠2 小时前
[leetcode] 165. Compare Version Numbers
java·算法·leetcode