侧边栏壁纸
博主头像
colo

欲买桂花同载酒

  • 累计撰写 1823 篇文章
  • 累计收到 0 条评论

请解释Java中synchronized关键字的用途,并说明它可以应用在哪些地方?

2025-12-13 / 0 评论 / 4 阅读

题目

请解释Java中synchronized关键字的用途,并说明它可以应用在哪些地方?

信息

  • 类型:问答
  • 难度:⭐

考点

synchronized关键字,线程同步,锁机制

快速回答

synchronized关键字用于解决多线程环境下的数据竞争问题,主要用途是:

  • 确保同一时刻只有一个线程能访问被保护的代码块或方法
  • 保证线程对共享资源操作的可见性和原子性

应用位置:

  1. 实例方法:锁定当前对象实例
  2. 静态方法:锁定当前类的Class对象
  3. 代码块:可指定任意对象作为锁
## 解析

一、核心原理

synchronized是Java内置的互斥锁机制,通过对象监视器(Monitor)实现:

  • 当线程进入synchronized区域时,自动获取锁
  • 其他线程尝试获取同一锁时会被阻塞
  • 线程执行完同步代码后自动释放锁

二、代码示例

// 1. 实例方法同步
class Counter {
    private int count = 0;

    public synchronized void increment() {
        count++; // 线程安全操作
    }
}

// 2. 静态方法同步
class Logger {
    public static synchronized void log(String msg) {
        System.out.println(msg);
    }
}

// 3. 同步代码块
class SafeList {
    private final List<String> list = new ArrayList<>();
    private final Object lock = new Object();

    public void add(String item) {
        synchronized (lock) { // 显式指定锁对象
            list.add(item);
        }
    }
}

三、最佳实践

  • 减小同步范围:优先使用代码块而非整个方法
  • 避免锁嵌套:防止死锁(如线程A持有锁1请求锁2,线程B持有锁2请求锁1)
  • 使用final对象锁:防止锁对象被意外修改
  • 替代方案:简单场景可用java.util.concurrent.atomic包下的原子类

四、常见错误

  • 错误1:同步不同对象
    示例:synchronized(new Object()){...}(每次锁不同对象)
  • 错误2:误用字符串常量锁
    示例:synchronized("LOCK")(可能与其他代码意外互斥)
  • 错误3:忘记同步setter/getter
    示例:非同步的get方法可能读到未完全构造的对象

五、扩展知识

  • 锁升级机制:JDK6后优化为偏向锁→轻量级锁→重量级锁
  • 与ReentrantLock对比:synchronized更简单,ReentrantLock支持公平锁和条件变量
  • happens-before原则:synchronized保证解锁前的操作对加锁线程可见