1 synchronized 关键字的作用
- 互斥访问:
当一个线程获得了由 synchronized 修饰的方法或代码块的锁后,其他线程必须等待该锁被释放才能继续执行。
这种机制保证了同一时间只有一个线程可以执行被 synchronized 修饰的代码段。 - 可见性:
synchronized 关键字确保了当一个线程修改了共享变量后,这些修改对其他线程是可见的。
当一个线程释放锁时,它会强制刷新线程的工作内存到主内存,其他线程在获取锁时会从主内存中读取最新的变量值。 - 有序性:
synchronized 关键字保证了在 synchronized 代码块中的操作按照它们出现的顺序执行,防止了指令重排序。
2 synchronized 的使用
2.1 修饰方法
public synchronized void method() {
// ...
}
- 当一个方法被 synchronized 修饰时,它会在该方法的入口处获取锁,在方法结束或抛出异常时释放锁。
- 锁的对象是当前对象的实例(如果是实例方法)或类对象(如果是静态方法)。
2.2 修饰代码块
public void method() {
synchronized (lockObject) {
// ...
}
}
- 当一个代码块被 synchronized 修饰时,它会获取指定对象的锁。
- 锁的对象可以是任何对象,通常使用一个私有静态的锁对象来确保线程安全。
3 底层实现原理
synchronized 关键字的底层实现涉及到 Java 对象的监视器锁(Monitor)。每个 Java 对象都可以成为一个监视器锁,当一个线程获取了某个对象的锁后,其他线程必须等待该锁被释放才能继续执行。监视器锁的信息存储在 Java 对象头中。