Java 并发编程之锁:从 Synchronized 到 ReentrantLock,再探乐观与公平
前言:为何需要锁?
在多线程并发编程中,当多个线程需要访问和修改共享资源(如共享变量、对象、文件等)时,如果没有适当的同步机制,就可能导致数据竞争(Race Condition)、数据不一致等问题。锁(Lock) 就是 Java 中最基本、最重要的线程同步机制之一,它用于控制多个线程对共享资源的访问权限,保证在同一时刻只有一个(或有限个)线程能够访问被保护的资源,从而确保线程安全。
本文将带你深入了解 Java 中常见的锁机制和相关概念。
- 理解锁的基本作用。
- 掌握
synchronized关键字的使用和原理。 - 掌握
ReentrantLock的使用和特性。 - 清晰辨析
synchronized与ReentrantLock的核心区别。 - 理解悲观锁和乐观锁的设计思想。
- 理解公平锁和非公平锁的区别与权衡。
Java 内置锁:synchronized
synchronized 是 Java 语言层面的关键字,也是最基础、最常用的内置锁。它依赖于 JVM 实现,背后关联着每个 Java 对象都拥有的监视器锁(Monitor Lock),也称为内部锁(Intrinsic Lock)。
使用方式:
- 修饰实例方法: 锁对象是当前实例 (
this)。public synchronized void instanceMethod() { // 同步代码块,访问实例资源 } - 修饰静态方法: 锁对象是当前类的
Class对象。public static synchronized void staticMethod() { // 同步代码块,访问静态资源 } - 修饰代码块: 可以显式指定锁对象,更加灵活。
Object lock = new Object(); public void blockMethod() { synchronized (lock) { // 使用指定对象作为锁 // 同步代码块 } synchronized (this) { // 使用当前实例作为锁 // 另一个同步代码块 } synchronized (MyClass.class) { // 使用类对象作为锁 // 访问静态资源的同步代码块 } }
synchronized 的特性:



