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

Java中volatile关键字未生效,代码是否存在错误?

问题分析与解决

你的代码核心问题

你的代码里thread1和thread2是两个独立的MutliThreadExample实例,每个实例都有自己的value成员变量。两个线程分别操作各自实例的value,完全不存在变量共享的场景,所以volatile关键字在这里根本发挥不了作用——加不加它,两个线程的操作都互不干扰,输出结果自然一致。

什么场景下volatile才有用

volatile的核心作用是保证共享变量的可见性(一个线程修改变量后,其他线程能立刻看到最新值),同时禁止指令重排序。只有当多个线程同时操作同一个共享变量时,它的效果才会体现出来。

修改后的示例代码

要验证volatile的作用,需要让多个线程操作同一个共享变量,以下是两种可行的修改方式:

方式1:使用static共享变量

public class MutliThreadExample extends Thread{

    // 改为static,让所有线程共享这个变量
    static volatile int value;
    
    public static void main(String[] args) throws InterruptedException {
        MutliThreadExample thread1 = new MutliThreadExample();
        MutliThreadExample thread2 = new MutliThreadExample();
        thread1.start();
        // 去掉join,让两个线程同时运行
        thread2.start();
    }

    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            value = value + 1;
            System.out.println(value + "-" + Thread.currentThread().getName());
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

方式2:共用同一个实例

public class MutliThreadExample implements Runnable{

    volatile int value;
    
    public static void main(String[] args) throws InterruptedException {
        MutliThreadExample sharedInstance = new MutliThreadExample();
        Thread thread1 = new Thread(sharedInstance);
        Thread thread2 = new Thread(sharedInstance);
        thread1.start();
        thread2.start();
    }

    @Override
    public void run() {
        for (int i = 1; i <= 5; i++) {
            value = value + 1;
            System.out.println(value + "-" + Thread.currentThread().getName());
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

补充说明

注意:volatile不能解决原子性问题,比如value = value + 1这个操作是非原子的(包含读取、加1、写入三步),即使加了volatile,也可能出现线程安全问题(比如两个线程同时读取到相同的值,加1后写入导致最终值比预期小)。如果要保证原子性,需要配合synchronized或者使用AtomicInteger类。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:37:13