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

Java中对Integer对象加synchronized锁未生效的原因是什么

问题错误原因
  • 锁对象不是固定值:Java中Integer是不可变类,代码中count += 1的操作本质是生成新的Integer实例赋值给count变量,等价于count = Integer.valueOf(count.intValue() + 1)。你将synchronized锁加在频繁变化的count对象上,会导致两个线程可能同时持有不同的锁对象进入临界区,自增操作的原子性无法得到保障,最终计数结果小于预期。
  • Integer缓存特性加剧问题:Integer默认会缓存-128~127范围内的实例,当count数值还在该区间时,多个线程加锁的是同一个对象,此时不会出现并发问题;一旦count超过127,每次自增都会生成全新的Integer对象,锁直接失效,大量并发冲突会导致计数丢失。
修复方案

方案1:使用固定锁对象

声明一个不会发生变更的对象作为synchronized的锁,保证所有线程竞争的是同一把锁:

public class Test {
    // 改用基础类型int避免不必要的装箱拆箱
    private static int count = 0;
    // 固定锁对象,final修饰保证不会被修改
    private static final Object LOCK = new Object();

    private static void add10K() {
        long idx = 0;
        while (idx++ < 1_0000_0000) {
            synchronized (LOCK){
                count += 1;
            }
        }
    }

    public static long calc() {
        Thread th1 = new Thread(Test::add10K);
        Thread th2 = new Thread(Test::add10K);
        th1.start();
        th2.start();
        try {
            th1.join();
            th2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return count;
    }

    public static void main(String[] args) {
        System.out.println(calc());
    }
}

方案2:使用原子类优化性能

对于计数类场景,可以直接使用JUC包提供的原子类实现无锁原子操作,性能远高于手动加synchronized:

import java.util.concurrent.atomic.AtomicInteger;

public class Test {
    // 原子整数类,自带原子操作能力
    private static AtomicInteger count = new AtomicInteger(0);

    private static void add10K() {
        long idx = 0;
        while (idx++ < 1_0000_0000) {
            // 原子自增,无需手动加锁
            count.incrementAndGet();
        }
    }

    public static long calc() {
        Thread th1 = new Thread(Test::add10K);
        Thread th2 = new Thread(Test::add10K);
        th1.start();
        th2.start();
        try {
            th1.join();
            th2.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return count.get();
    }

    public static void main(String[] args) {
        System.out.println(calc());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 20:06:02