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

Java中使用synchronized方法递增int变量时,是否必须声明为volatile?

使用synchronized方法时,是否还需要用volatile修饰变量?

结论很明确:不需要,仅用synchronized方法就足够保证多线程环境下递增操作的线程安全,以及变量的可见性。

核心原因:

  • synchronized本身具备完整的内存语义:线程进入synchronized方法/代码块时,会强制从主内存读取变量最新值到自身工作内存;退出同步区域时,会将工作内存中修改后的变量值写回主内存,同时让其他线程工作内存中该变量的缓存失效,确保后续读取的都是最新值。
  • 你代码里的increment()方法是synchronized的,counter++这个包含「读取-修改-写入」的三步操作会被完整加锁保护,既避免了多线程下的原子性问题,也通过synchronized的内存语义保证了counter变量的可见性。

代码相关补充说明:

你的Counter类中,getCounter()方法未加synchronized,如果该方法会被多个线程并发调用,可能读取到旧的counter值——但这和是否给counter加volatile无关,解决方式要么给getCounter()也加上synchronized,要么确保只有当所有increment操作完成后才调用getCounter()(就像你测试代码里等待线程池终止后再读取的逻辑),这种场景下也不会有问题。

至于你看到讲师同时使用synchronized方法和volatile变量,这属于冗余写法,实际场景中完全没必要——synchronized已经覆盖了volatile能提供的可见性保障,还额外提供了原子性保障。

你的代码示例:

ClientTest 类

public class ClientTest {
    public static void main(String[] args) {
        ExecutorService executorService = null;
        Counter counter = new Counter();

        try {
            executorService = Executors.newFixedThreadPool(2);

            Runnable task1 = () -> {
                for (int i = 1; i <= 20000; i++) {
                    counter.increment();
                }
            };

            Runnable task2 = () -> {
                for (int i = 1; i <= 80000; i++) {
                    counter.increment();
                }
            };

            executorService.submit(task1);
            executorService.submit(task2);
            executorService.awaitTermination(1, TimeUnit.SECONDS);

            System.out.println("Final counter value: " + counter.getCounter());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

Counter 类

public class Counter {
    private int counter;
    public int getCounter() {
        return counter;
    }
    public synchronized void increment() {
        counter++;
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 04:57:34