You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

synchronized关键字能否解决可见性问题?测试结果存疑求解

为什么加了synchronized后无volatile也能得到正确结果?

首先看你的代码:

class Q2 {
    static long value;

    public static void main(String[] args) throws InterruptedException{
        Runnable r = () -> {
            for (int i = 0; i < 100000000; i++) {
                synchronized (Q2.class) {
                    value++;    
                }
            }
        };

        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        
        t1.start();
        t2.start();

        Thread.sleep(100000); //wait enough time

        System.out.println("value = " + value);
    }
}

这不是巧合,synchronized本身就同时保证了原子性、可见性和有序性,完全覆盖了你担心的可见性问题:

  • 线程进入synchronized块时,会强制从主内存加载共享变量的最新值,不会使用本地缓存的旧数据;
  • 线程退出synchronized块时,会把对共享变量的修改同步回主内存,确保其他线程能立即看到更新。

你的代码里,每次value++都被包裹在synchronized块中,带来两个关键保障:

  • 原子性:避免了多线程同时执行value++(这是个读-改-写操作)导致的数值覆盖;
  • 可见性:每次读取和修改value都直接和主内存交互,不存在线程间数据不可见的情况。

而volatile关键字仅负责可见性和禁止指令重排序,不保证原子性。这里synchronized已经提供了足够的线程安全保障,所以不需要额外添加volatile也能稳定得到200000000的结果。

内容的提问来源于stack exchange,提问作者YouHoGeon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 00:12:54