Java 锁机制深度解析

目录

  1. Java锁体系概览
  2. synchronized 内置锁
  3. ReentrantLock 可重入锁
  4. ReentrantReadWriteLock 读写锁
  5. StampedLock 邮戳锁
  6. Semaphore 信号量
  7. CountDownLatch 闭锁
  8. CyclicBarrier 循环屏障
  9. Phaser 阶段器
  10. LockSupport 锁支持
  11. 原子类(Atomic Classes)
  12. 锁的性能对比
  13. 最佳实践与选择指南

一、Java锁体系概览

1.1 Java锁分类

Java锁体系:

┌─────────────────────────────────────────────────────┐
│                   按锁的性质分类                      │
├──────────────────────────────────────────────────────┤
│                                                      │
│  1. 悲观锁 vs 乐观锁                                  │
│     - 悲观锁: synchronized, ReentrantLock            │
│     - 乐观锁: CAS操作, 原子类                         │
│                                                      │
│  2. 独占锁 vs 共享锁                                  │
│     - 独占锁: synchronized, ReentrantLock             │
│     - 共享锁: ReentrantReadWriteLock.ReadLock         │
│                                                      │
│  3. 公平锁 vs 非公平锁                                │
│     - 公平锁: ReentrantLock(true)                     │
│     - 非公平锁: synchronized, ReentrantLock(false)    │
│                                                      │
│  4. 可重入锁 vs 不可重入锁                             │
│     - 可重入锁: synchronized, ReentrantLock           │
│     - 不可重入锁: 自定义实现                           │
│                                                      │
│  5. 互斥锁 vs 读写锁                                  │
│     - 互斥锁: synchronized, ReentrantLock            │
│     - 读写锁: ReentrantReadWriteLock                 │
└─────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────┐
│                   按实现方式分类                     │
├─────────────────────────────────────────────────────┤
│                                                     │
│  1. 内置锁(JVM实现)                                │
│     - synchronized                                  │
│                                                     │
│  2. 显式锁(JDK实现)                                │
│     - ReentrantLock                                 │
│     - ReentrantReadWriteLock                        │
│     - StampedLock                                   │
│                                                     │
│  3. 同步工具类                                       │
│     - Semaphore                                     │
│     - CountDownLatch                                │
│     - CyclicBarrier                                 │
│     - Phaser                                        │
│                                                     │
│  4. 原子类(CAS实现)                                │
│     - AtomicInteger                                 │
│     - AtomicLong                                    │
│     - AtomicReference                               │
│     - AtomicStampedReference                        │
└─────────────────────────────────────────────────────┘

1.2 Java锁对比表

锁类型性质公平性可重入性能适用场景
synchronized独占、悲观非公平通用场景
ReentrantLock独占、悲观可选需要高级特性
ReentrantReadWriteLock读写分离可选读多写少
StampedLock读写分离非公平读多写少(JDK8+)
Semaphore共享、计数可选限流、资源控制
CountDownLatch一次性N/AN/A等待多个任务完成
CyclicBarrier可重用N/AN/A多线程同步点
Phaser分阶段N/AN/A复杂同步场景
AtomicInteger乐观锁N/AN/A极高计数器、状态标志

二、synchronized 内置锁

2.1 synchronized 基本用法

/**
 * synchronized 三种使用方式
 */
public class SynchronizedUsage {
    
    private int count = 0;
    private static int staticCount = 0;
    private final Object lock = new Object();
    
    /**
     * 方式1: 修饰实例方法
     */
    public synchronized void instanceMethod() {
        count++;
        // 锁对象是当前实例(this)。可以简单理解为:谁调用方法,谁就是锁对象 。
    }
    
    /**
     * 方式2: 修饰静态方法
     */
    public static synchronized void staticMethod() {
        staticCount++;
        // 锁对象是类对象(SynchronizedUsage.class)
    }
    
    /**
     * 方式3: 修饰代码块
     */
    public void blockMethod() {
        synchronized (lock) {
            count++;
            // 锁对象是指定的lock对象
        }
    }
}

2.2 synchronized 底层原理

2.2.1 字节码层面

工作原理

  1. MONITORENTER :尝试获取锁,如果成功则继续执行,否则阻塞当前线程
  2. 正常路径 MONITOREXIT :代码正常执行完成后释放锁
  3. 异常路径 MONITOREXIT :即使发生异常,也能确保锁被释放,避免死锁
/**
 * synchronized 字节码分析
 */
public class SynchronizedBytecode {
    
    public void synchronizedMethod() {
        synchronized (this) {
            // 业务逻辑
        }
    }
}

// 编译后的字节码(简化版):
/*
public synchronizedMethod()V
    ALOAD 0          // 加载this到操作数栈
    DUP              // 复制this引用
    ASTORE 1         // 存储到局部变量1(保存锁对象引用)
    MONITORENTER     // 进入监视器(获取锁)
    TRY_BLOCK_1:     // 开始try块
        // 业务逻辑代码
        GOTO END_BLOCK_1  // 跳过异常处理代码
    CATCH_BLOCK_1:   // 捕获异常的代码块
        ALOAD 1      // 加载局部变量1(this引用)
        MONITOREXIT  // 异常路径上的MONITOREXIT
        ATHROW       // 重新抛出异常
    END_BLOCK_1:     // 正常执行结束
        ALOAD 1      // 加载局部变量1(this引用)
        MONITOREXIT  // 正常路径上的MONITOREXIT
    RETURN           // 方法返回
*/

2.2.2 对象头与Mark Word
Java对象内存布局:

┌─────────────────────────────────────────────────────────────┐
│                   对象头(Object Header)                    │
├─────────────────────────────────────────────────────────────┤
│  Mark Word (64位):                                          │
│  [25位未使用][31位哈希码][1位未使用][4位年龄][1位偏向][2位锁标志]│
│                                                             │
│  锁标志位含义:                                                │
│    00: 轻量级锁(Lightweight Lock)                           │
│    01: 无锁/偏向锁(Normal/Biased)                           │
│    10: 重量级锁(Heavyweight Lock)                          │
│    11: GC标记(Marked for GC)                              │
│                                                            │
│  Class Metadata Pointer (64位):                            │
│    - 指向类的元数据(Klass)                                 │
│                                                            │
│  Array Length (可选,仅数组):                               │
│    - 数组长度                                               │
└────────────────────────────────────────────────────────────┘
2.2.3 锁升级过程详解
synchronized锁升级完整流程:

无锁状态(Normal)
  │
  │ 第一个线程访问
  ▼
偏向锁(Biased Lock)
  │
  │ 第二个线程竞争
  ▼
轻量级锁(Lightweight Lock)
  │
  │ 自旋失败或竞争激烈
  ▼
重量级锁(Heavyweight Lock)

详细过程:

阶段1: 偏向锁
  - 第一个线程访问时,JVM使用CAS将线程ID写入Mark Word
  - 后续同一线程访问时,无需CAS,直接进入
  - 性能最优(几乎无开销)
  
阶段2: 轻量级锁
  - 第二个线程竞争时,撤销偏向锁
  - 在栈帧中创建锁记录(Lock Record)
  - 使用CAS将Mark Word指向锁记录
  - 如果CAS成功 → 获取轻量级锁
  - 如果CAS失败 → 自旋等待或升级
  
阶段3: 重量级锁
  - 自旋失败(超过阈值)或竞争激烈
  - 创建Monitor对象
  - Mark Word指向Monitor对象
  - 线程进入阻塞队列(EntryList)
  - 操作系统级别的阻塞(Mutex)

2.3 Monitor对象深入解析

/**
 * Monitor对象结构(概念模型)
 * 
 * 注意:实际实现是C++代码(ObjectMonitor)
 */
public class ObjectMonitor {
    /**
     * 持有锁的线程
     */
    private Thread owner;
    /**
     * 重入次数
     */
    private int recursions;

    /**
     * 等待队列(调用wait()的线程)
     */
    private WaitSet waitSet;
    /**
     * 阻塞队列(竞争锁的线程)
     */
    private EntryList entryList;
    /**
     * 获取锁
     */
    public void enter() {
        Thread currentThread = Thread.currentThread();
        // 1. 尝试快速获取锁(CAS)
        if (compareAndSetOwner(null, currentThread)) {
            recursions = 1;
            return;
        }
        // 2. 重入检查
        if (owner == currentThread) {
            recursions++;
            return;
        }
        // 3. 获取锁失败,进入阻塞队列
        entryList.add(currentThread);
        // 4. 操作系统级别的阻塞(park)
        park(currentThread);
    }
    
    /**
     * 释放锁
     */
    public void exit() {
        Thread currentThread = Thread.currentThread();
        if (owner != currentThread) {
            throw new IllegalMonitorStateException();
        }
        if (--recursions > 0) {
            return;  // 还有重入,不释放
        }
        owner = null;
        // 唤醒阻塞队列中的线程
        Thread nextThread = entryList.remove();
        if (nextThread != null) {
            unpark(nextThread);
        }
    }
    
    /**
     * 等待(释放锁,进入等待队列)
     */
    public void wait() {
        Thread currentThread = Thread.currentThread();
        if (owner != currentThread) {
            throw new IllegalMonitorStateException();
        }
        int savedRecursions = recursions;
        owner = null;
        recursions = 0;
        // 进入等待队列
        waitSet.add(currentThread);
        // 唤醒阻塞队列中的线程
        Thread nextThread = entryList.remove();
        if (nextThread != null) {
            unpark(nextThread);
        }
        // 阻塞当前线程
        park(currentThread);
        // 被唤醒后,重新获取锁
        enter();
        recursions = savedRecursions;
    }
    
    /**
     * 通知(唤醒等待队列中的线程)
     */
    public void notify() {
        Thread currentThread = Thread.currentThread();
        
        if (owner != currentThread) {
            throw new IllegalMonitorStateException();
        }
        
        Thread waitingThread = waitSet.remove();
        if (waitingThread != null) {
            entryList.add(waitingThread);
        }
    }
}

2.4 synchronized 性能优化

synchronized性能优化机制:

1. 偏向锁(Biased Locking)
   - 目的: 优化无竞争场景
   - 原理: 第一个线程访问时,将线程ID写入Mark Word
   - 优势: 同一线程再次访问时无需CAS操作
   - 劣势: 有竞争时需要撤销,开销较大

2. 轻量级锁(Lightweight Locking)
   - 目的: 优化低竞争场景
   - 原理: 使用CAS和栈帧中的锁记录
   - 优势: 线程不会阻塞(自旋等待)
   - 劣势: 自旋消耗CPU

3. 自适应自旋(Adaptive Spinning)
   - 目的: 优化自旋次数
   - 原理: 根据历史成功率动态调整自旋次数
   - 优势: 平衡CPU消耗和响应时间

4. 锁粗化(Lock Coarsening)
   - 目的: 减少锁的获取和释放次数
   - 原理: 将连续的synchronized块合并
   - 优势: 减少开销

5. 锁消除(Lock Elimination)
   - 目的: 消除不必要的锁
   - 原理: 逃逸分析证明对象不会逃逸
   - 优势: 完全消除锁开销

三、ReentrantLock 可重入锁

3.1 ReentrantLock 基本用法

/**
 * ReentrantLock 基本用法
 */
public class ReentrantLockUsage {
    private final ReentrantLock lock = new ReentrantLock();
    /**
     * 基本用法
     */
    public void basicUsage() {
        lock.lock();
        try {
            // 业务逻辑
        } finally {
            lock.unlock();
        }
    }
    /**
     * 尝试获取锁(非阻塞)
     */
    public void tryLockUsage() {
        if (lock.tryLock()) {
            try {
                // 业务逻辑
            } finally {
                lock.unlock();
            }
        } else {
            // 获取锁失败的处理
        }
    }
    
    /**
     * 带超时的获取锁
     */
    public void tryLockWithTimeout() throws InterruptedException {
        if (lock.tryLock(5, TimeUnit.SECONDS)) {
            try {
                // 业务逻辑
            } finally {
                lock.unlock();
            }
        } else {
            // 超时未获取到锁
        }
    }
    
    /**
     * 可中断的获取锁
     */
    public void interruptibleLock() throws InterruptedException {
        lock.lockInterruptibly();
        try {
            // 业务逻辑
        } finally {
            lock.unlock();
        }
    }
}

3.2 ReentrantLock 核心特性

ReentrantLock 核心特性:

1. 可重入性
   - 同一线程可以多次获取同一把锁
   - 内部维护重入次数计数器
   - 释放锁时需要释放相同次数

2. 公平性
   - 公平锁: 按照请求顺序获取锁(FIFO)
   - 非公平锁: 允许插队(性能更好)
   - 默认: 非公平锁

3. 可中断性
   - lockInterruptibly()支持中断
   - 等待锁时可以被中断

4. 条件变量
   - 支持多个Condition
   - 可以实现更复杂的同步场景

3.3 AQS(AbstractQueuedSynchronizer)原理

3.3.1 AQS核心设计
AQS核心设计思想:

┌─────────────────────────────────────────────────────────┐
│                   AQS设计模式                            │
├─────────────────────────────────────────────────────────┤
│                                                         │
│  模板方法模式:                                           │
│    - acquire(): 模板方法(固定流程)                      │
│    - tryAcquire(): 钩子方法(由子类实现)                 │
│                                                         │
│  核心组件:                                               │
│    - state: 同步状态(volatile int)                     │
│    - head: 同步队列头节点                                │
│    - tail: 同步队列尾节点                                │
│    - Node: 等待队列节点                                  │
│                                                         │
│  同步队列(CLH队列变种):                                 │
│    - 双向链表结构                                        │
│    - 每个节点代表一个等待的线程                           │
│    - 支持公平锁和非公平锁                                 │
└─────────────────────────────────────────────────────────┘
3.3.2 AQS同步队列结构
/**
 * AQS同步队列节点结构
 */
static final class Node {
    /**
     * 节点模式
     */
    static final Node SHARED = new Node();  // 共享模式
    static final Node EXCLUSIVE = null;      // 独占模式
    
    /**
     * 等待状态
     */
    volatile int waitStatus;
    
    static final int CANCELLED =  1;  // 已取消
    static final int SIGNAL    = -1;  // 需要唤醒后继节点
    static final int CONDITION = -2;  // 在条件队列中
    static final int PROPAGATE = -3;  // 共享模式传播
    
    /**
     * 前驱节点
     */
    volatile Node prev;
    
    /**
     * 后继节点
     */
    volatile Node next;
    
    /**
     * 等待的线程
     */
    volatile Thread thread;
    
    /**
     * 条件队列中的下一个节点
     */
    Node nextWaiter;
}
3.3.3 AQS获取锁完整流程
/**
 * AQS获取锁完整流程(源码级别)
 */
public abstract class AbstractQueuedSynchronizer {
    
    /**
     * 获取独占锁(模板方法)
     */
    public final void acquire(int arg) {
        // 1. 尝试获取锁
        if (!tryAcquire(arg) &&
            // 2. 获取失败,加入队列并自旋
            acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) {
            // 3. 如果被中断,恢复中断状态
            selfInterrupt();
        }
    }
    
    /**
     * 尝试获取锁(由子类实现)
     */
    protected boolean tryAcquire(int arg) {
        throw new UnsupportedOperationException();
    }
    
    /**
     * 加入同步队列
     */
    private Node addWaiter(Node mode) {
        Node node = new Node(Thread.currentThread(), mode);
        Node pred = tail;
        
        if (pred != null) {
            node.prev = pred;
            // CAS设置尾节点
            if (compareAndSetTail(pred, node)) {
                pred.next = node;
                return node;
            }
        }
        
        // CAS失败,使用enq方法(自旋重试)
        enq(node);
        return node;
    }
    
    /**
     * 在队列中自旋获取锁
     */
    final boolean acquireQueued(final Node node, int arg) {
        boolean failed = true;
        try {
            boolean interrupted = false;
            for (;;) {
                final Node p = node.predecessor();
                // 如果前驱节点是头节点,尝试获取锁
                if (p == head && tryAcquire(arg)) {
                    setHead(node);
                    p.next = null; // help GC
                    failed = false;
                    return interrupted;
                }
                // 检查是否需要阻塞
                if (shouldParkAfterFailedAcquire(p, node) &&
                    parkAndCheckInterrupt()) {
                    interrupted = true;
                }
            }
        } finally {
            if (failed) {
                cancelAcquire(node);
            }
        }
    }
    
    /**
     * 检查是否需要阻塞
     */
    private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) {
        int ws = pred.waitStatus;
        if (ws == Node.SIGNAL) {
            // 前驱节点需要唤醒后继节点,可以安全阻塞
            return true;
        }
        if (ws > 0) {
            // 前驱节点已取消,跳过
            do {
                node.prev = pred = pred.prev;
            } while (pred.waitStatus > 0);
            pred.next = node;
        } else {
            // 设置前驱节点为SIGNAL状态
            compareAndSetWaitStatus(pred, ws, Node.SIGNAL);
        }
        return false;
    }
    
    /**
     * 阻塞并检查中断
     */
    private final boolean parkAndCheckInterrupt() {
        LockSupport.park(this);
        return Thread.interrupted();
    }
}

3.4 ReentrantLock 公平锁 vs 非公平锁

/**
 * ReentrantLock 公平锁与非公平锁实现对比
 */
public class ReentrantLockFairness {
    
    /**
     * 非公平锁实现
     */
    static final class NonfairSync extends Sync {
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            
            if (c == 0) {
                // 非公平锁:直接尝试获取,不检查队列
                if (compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            } else if (current == getExclusiveOwnerThread()) {
                // 重入
                int nextc = c + acquires;
                if (nextc < 0) {
                    throw new Error("Maximum lock count exceeded");
                }
                setState(nextc);
                return true;
            }
            return false;
        }
    }
    
    /**
     * 公平锁实现
     */
    static final class FairSync extends Sync {
        protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            
            if (c == 0) {
                // 公平锁:检查是否有前驱节点
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            } else if (current == getExclusiveOwnerThread()) {
                // 重入
                int nextc = c + acquires;
                if (nextc < 0) {
                    throw new Error("Maximum lock count exceeded");
                }
                setState(nextc);
                return true;
            }
            return false;
        }
        
        /**
         * 检查是否有前驱节点
         */
        public final boolean hasQueuedPredecessors() {
            Node t = tail;
            Node h = head;
            Node s;
            return h != t &&
                ((s = h.next) == null || s.thread != Thread.currentThread());
        }
    }
}

3.5 Condition 条件变量

/**
 * Condition 条件变量使用
 */
public class ConditionUsage {
    
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private boolean flag = false;
    
    /**
     * 等待条件
     */
    public void awaitCondition() throws InterruptedException {
        lock.lock();
        try {
            while (!flag) {
                // 释放锁,进入等待队列
                condition.await();
            }
            // 条件满足,执行业务逻辑
            doSomething();
        } finally {
            lock.unlock();
        }
    }
    
    /**
     * 通知条件满足
     */
    public void signalCondition() {
        lock.lock();
        try {
            flag = true;
            // 唤醒等待队列中的一个线程
            condition.signal();
            // 或者唤醒所有等待的线程
            // condition.signalAll();
        } finally {
            lock.unlock();
        }
    }
    
    /**
     * 生产者-消费者示例
     */
    public class ProducerConsumer {
        private final ReentrantLock lock = new ReentrantLock();
        private final Condition notFull = lock.newCondition();
        private final Condition notEmpty = lock.newCondition();
        private final Queue<String> queue = new LinkedList<>();
        private final int capacity = 10;
        
        public void produce(String item) throws InterruptedException {
            lock.lock();
            try {
                while (queue.size() == capacity) {
                    // 队列满,等待
                    notFull.await();
                }
                queue.offer(item);
                // 通知消费者
                notEmpty.signal();
            } finally {
                lock.unlock();
            }
        }
        
        public String consume() throws InterruptedException {
            lock.lock();
            try {
                while (queue.isEmpty()) {
                    // 队列空,等待
                    notEmpty.await();
                }
                String item = queue.poll();
                // 通知生产者
                notFull.signal();
                return item;
            } finally {
                lock.unlock();
            }
        }
    }
}

四、ReentrantReadWriteLock 读写锁

4.1 读写锁基本概念

读写锁原理:

┌───────────────────────────────────────────────┐
│                   读写锁特性                   │
├───────────────────────────────────────────────┤
│                                               │
│  读锁(共享锁):                               │
│    - 多个线程可以同时持有读锁                   │
│    - 读锁与读锁不互斥                          │
│    - 读锁与写锁互斥                            │
│                                               │
│  写锁(独占锁):                               │
│    - 同一时刻只有一个线程可以持有写锁            │
│    - 写锁与读锁互斥                             │
│    - 写锁与写锁互斥                             │
│                                               │
│  锁降级:                                       │
│    - 写锁可以降级为读锁                         │
│    - 读锁不能升级为写锁                         │
└───────────────────────────────────────────────┘

锁的兼容性矩阵:

读锁写锁
读锁
写锁

4.2 ReentrantReadWriteLock 实现原理

4.2.1 状态位设计
ReentrantReadWriteLock 状态位设计:

state (32位):
  ┌─────────────────────────────────────────┐
  │ 高16位: 读锁持有数量                     │
  │ 低16位: 写锁重入次数                     │
  └─────────────────────────────────────────┘

示例:
  state = 0x00010001
  - 高16位: 0x0001 = 1(1个线程持有读锁)
  - 低16位: 0x0001 = 1(写锁重入1次)

读锁获取:
  - 检查写锁是否被持有(state低16位是否为0)
  - 如果写锁未被持有,增加读锁计数(高16位+1)
  
写锁获取:
  - 检查读锁和写锁是否都被持有(state是否为0)
  - 如果都为0,设置写锁状态(低16位=1)
4.2.2 读写锁实现源码
/**
 * ReentrantReadWriteLock 核心实现
 */
public class ReentrantReadWriteLock implements ReadWriteLock {
    
    private final ReadLock readLock;
    private final WriteLock writeLock;
    private final Sync sync;
    
    /**
     * 同步器(继承AQS)
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        
        // 读锁和写锁共享同一个state
        // 高16位:读锁计数
        // 低16位:写锁重入次数
        
        static final int SHARED_SHIFT   = 16;
        static final int SHARED_UNIT    = (1 << SHARED_SHIFT);
        static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;
        static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;
        
        /**
         * 获取读锁数量
         */
        static int sharedCount(int c) {
            return c >>> SHARED_SHIFT;
        }
        
        /**
         * 获取写锁重入次数
         */
        static int exclusiveCount(int c) {
            return c & EXCLUSIVE_MASK;
        }
        
        /**
         * 读锁获取
         */
        protected final int tryAcquireShared(int unused) {
            Thread current = Thread.currentThread();
            int c = getState();
            
            // 如果写锁被持有,且不是当前线程持有,获取失败
            if (exclusiveCount(c) != 0 &&
                getExclusiveOwnerThread() != current) {
                return -1;
            }
            
            int r = sharedCount(c);
            if (!readerShouldBlock() &&
                r < MAX_COUNT &&
                compareAndSetState(c, c + SHARED_UNIT)) {
                // 获取读锁成功
                return 1;
            }
            
            return fullTryAcquireShared(current);
        }
        
        /**
         * 写锁获取
         */
        protected final boolean tryAcquire(int acquires) {
            Thread current = Thread.currentThread();
            int c = getState();
            int w = exclusiveCount(c);
            
            if (c != 0) {
                // 如果读锁被持有,或者写锁被其他线程持有
                if (w == 0 || current != getExclusiveOwnerThread()) {
                    return false;
                }
                // 写锁重入
                if (w + acquires > EXCLUSIVE_MASK) {
                    throw new Error("Maximum lock count exceeded");
                }
                setState(c + acquires);
                return true;
            }
            
            // 尝试获取写锁
            if (writerShouldBlock() ||
                !compareAndSetState(c, c + acquires)) {
                return false;
            }
            
            setExclusiveOwnerThread(current);
            return true;
        }
    }
}

4.3 读写锁使用示例

/**
 * 读写锁实际应用示例
 */
@Service
@Slf4j
public class ReadWriteLockExample {
    
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
    private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
    
    private Map<String, String> cache = new HashMap<>();
    
    /**
     * 读操作(多个线程可以并发读取)
     */
    public String get(String key) {
        readLock.lock();
        try {
            return cache.get(key);
        } finally {
            readLock.unlock();
        }
    }
    
    /**
     * 写操作(独占访问)
     */
    public void put(String key, String value) {
        writeLock.lock();
        try {
            cache.put(key, value);
        } finally {
            writeLock.unlock();
        }
    }
    
    /**
     * 锁降级示例
     */
    public void lockDowngrade(String key, String value) {
        writeLock.lock();
        try {
            // 写操作
            cache.put(key, value);
            
            // 锁降级:写锁降级为读锁
            readLock.lock();
        } finally {
            writeLock.unlock();  // 释放写锁
        }
        
        try {
            // 读操作(仍然持有读锁)
            String result = cache.get(key);
            // 处理结果...
        } finally {
            readLock.unlock();
        }
    }
}

五、StampedLock 邮戳锁

5.1 StampedLock 简介

StampedLock 特性(JDK 8+):

┌────────────────────────────────────────────────────────┐
│                   StampedLock 特点                     │
├────────────────────────────────────────────────────────┤
│                                                        │
│  1. 三种模式:                                           │
│     - 写锁(Write Lock): 独占锁                         │
│     - 悲观读锁(Pessimistic Read Lock): 类似读锁        │
│     - 乐观读(Optimistic Read): 无锁读取                │
│                                                        │
│  2. 性能优势:                                           │
│     - 乐观读性能极高(无锁)                             │
│     - 适合读多写少场景                                   │
│                                                        │
│  3. 限制:                                              │
│     - 不可重入                                          │
│     - 不支持条件变量(Condition)                        │
│     - 不支持公平锁                                      │
└───────────────────────────────────────────────────────┘

5.2 StampedLock 实现原理

/**
 * StampedLock 使用示例
 */
public class StampedLockUsage {
    
    private final StampedLock stampedLock = new StampedLock();
    private double x, y;
    
    /**
     * 写锁
     */
    public void write(double newX, double newY) {
        long stamp = stampedLock.writeLock();
        try {
            x = newX;
            y = newY;
        } finally {
            stampedLock.unlockWrite(stamp);
        }
    }
    
    /**
     * 悲观读锁
     */
    public double read() {
        long stamp = stampedLock.readLock();
        try {
            return Math.sqrt(x * x + y * y);
        } finally {
            stampedLock.unlockRead(stamp);
        }
    }
    
    /**
     * 乐观读(推荐)
     */
    public double optimisticRead() {
        // 1. 尝试乐观读(不获取锁)
        long stamp = stampedLock.tryOptimisticRead();
        double currentX = x;
        double currentY = y;
        
        // 2. 验证stamp是否有效(检查是否有写操作)
        if (!stampedLock.validate(stamp)) {
            // 3. 乐观读失败,升级为悲观读锁
            stamp = stampedLock.readLock();
            try {
                currentX = x;
                currentY = y;
            } finally {
                stampedLock.unlockRead(stamp);
            }
        }
        
        return Math.sqrt(currentX * currentX + currentY * currentY);
    }
    
    /**
     * 锁升级(读锁升级为写锁)
     */
    public void upgradeReadToWrite() {
        long stamp = stampedLock.readLock();
        try {
            // 读操作
            double currentX = x;
            
            // 尝试升级为写锁
            long writeStamp = stampedLock.tryConvertToWriteLock(stamp);
            if (writeStamp == 0) {
                // 升级失败,释放读锁,获取写锁
                stampedLock.unlockRead(stamp);
                writeStamp = stampedLock.writeLock();
            }
            
            try {
                // 写操作
                x = currentX + 1;
            } finally {
                stampedLock.unlockWrite(writeStamp);
            }
        } finally {
            // 如果升级失败,这里stamp已经无效
        }
    }
}

5.3 StampedLock vs ReentrantReadWriteLock

性能对比(读多写少场景):

┌───────────────────────────────────────────────────────┐
│            StampedLock vs ReentrantReadWriteLock      │
├──────────────┬──────────┬─────────────────────────────┤
│ 特性         │ StampedLock │ ReentrantReadWriteLock   │
├──────────────┼──────────┼─────────────────────────────┤
│ 乐观读       │ ✅       │ ❌                          │
│ 可重入       │ ❌       │ ✅                          │
│ 条件变量     │ ❌       │ ✅                          │
│ 公平锁       │ ❌       │ ✅                          │
│ 读性能       │ ⭐⭐⭐⭐⭐ │ ⭐⭐⭐                 │
│ 写性能       │ ⭐⭐⭐⭐  │ ⭐⭐⭐⭐                │
│ 适用场景     │ 读多写少 │ 读多写少(需要重入)           │
└──────────────┴──────────┴─────────────────────────────┘

性能测试数据(1000万次读操作):
  ReentrantReadWriteLock: ~500ms
  StampedLock(乐观读): ~50ms(提升10倍)

六、Semaphore 信号量

6.1 Semaphore 基本概念

Semaphore 信号量:

┌───────────────────────────────────────────────────────┐
│                   信号量原理                           │
├───────────────────────────────────────────────────────┤
│                                                       │
│  概念:                                                │
│    - 控制同时访问资源的线程数量                         │
│    - 维护一组许可证(permits)                         │
│    - 获取许可证后才能访问资源                           │
│                                                       │
│  操作:                                                 │
│    - acquire(): 获取许可证(阻塞)                      │
│    - release(): 释放许可证                             │
│    - tryAcquire(): 尝试获取(非阻塞)                   │
│                                                       │
│  应用场景:                                             │
│    - 限流(限制并发数)                                 │
│    - 资源池管理                                        │
│    - 连接池控制                                        │
└───────────────────────────────────────────────────────┘

6.2 Semaphore 实现原理

/**
 * Semaphore 核心实现(基于AQS)
 */
public class Semaphore implements java.io.Serializable {
    
    private final Sync sync;
    
    /**
     * 同步器(共享模式)
     */
    abstract static class Sync extends AbstractQueuedSynchronizer {
        
        Sync(int permits) {
            setState(permits);  // 初始化许可证数量
        }
        
        /**
         * 获取许可证(共享模式)
         */
        protected int tryAcquireShared(int acquires) {
            for (;;) {
                int available = getState();
                int remaining = available - acquires;
                
                if (remaining < 0 ||
                    compareAndSetState(available, remaining)) {
                    return remaining;
                }
            }
        }
        
        /**
         * 释放许可证
         */
        protected boolean tryReleaseShared(int releases) {
            for (;;) {
                int current = getState();
                int next = current + releases;
                if (next < current) {
                    throw new Error("Maximum permit count exceeded");
                }
                if (compareAndSetState(current, next)) {
                    return true;
                }
            }
        }
    }
}

6.3 Semaphore 使用示例

/**
 * Semaphore 实际应用示例
 */
@Service
@Slf4j
public class SemaphoreExample {
    
    /**
     * 场景1: 限流(限制并发请求数)
     */
    public class RateLimiter {
        private final Semaphore semaphore;
        
        public RateLimiter(int maxConcurrent) {
            this.semaphore = new Semaphore(maxConcurrent);
        }
        
        public <T> T execute(Supplier<T> supplier) throws InterruptedException {
            semaphore.acquire();  // 获取许可证
            try {
                return supplier.get();
            } finally {
                semaphore.release();  // 释放许可证
            }
        }
    }
    
    /**
     * 场景2: 连接池管理
     */
    public class ConnectionPool {
        private final Semaphore semaphore;
        private final Queue<Connection> connections;
        
        public ConnectionPool(int poolSize) {
            this.semaphore = new Semaphore(poolSize);
            this.connections = new ConcurrentLinkedQueue<>();
            // 初始化连接池
            for (int i = 0; i < poolSize; i++) {
                connections.offer(createConnection());
            }
        }
        
        public Connection getConnection() throws InterruptedException {
            semaphore.acquire();  // 获取许可证
            return connections.poll();
        }
        
        public void releaseConnection(Connection conn) {
            connections.offer(conn);
            semaphore.release();  // 释放许可证
        }
        
        private Connection createConnection() {
            // 创建连接
            return null;
        }
    }
    
    /**
     * 场景3: 批量任务控制
     */
    public class BatchTaskController {
        private final Semaphore semaphore = new Semaphore(10);  // 最多10个并发
        
        public void executeBatch(List<Runnable> tasks) {
            ExecutorService executor = Executors.newFixedThreadPool(20);
            
            for (Runnable task : tasks) {
                executor.submit(() -> {
                    try {
                        semaphore.acquire();
                        task.run();
                    } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                    } finally {
                        semaphore.release();
                    }
                });
            }
        }
    }
}

七、CountDownLatch 闭锁

7.1 CountDownLatch 基本概念

CountDownLatch 闭锁:

┌───────────────────────────────────────────────────┐
│                   闭锁原理                         │
├───────────────────────────────────────────────────┤
│                                                   │
│  概念:                                             │
│    - 一个或多个线程等待其他线程完成操作              │
│    - 计数器递减,减到0时唤醒等待的线程               │
│    - 一次性使用(计数器不能重置)                   │
│                                                   │
│  操作:                                             │
│    - await(): 等待计数器减到0                       │
│    - countDown(): 计数器减1                        │
│                                                    │
│  应用场景:                                          │
│    - 等待多个任务完成                               │
│    - 主线程等待子线程初始化完成                      │
│    - 并行计算后汇总结果                             │
└────────────────────────────────────────────────────┘

7.2 CountDownLatch 实现原理

/**
 * CountDownLatch 核心实现(基于AQS)
 */
public class CountDownLatch {
    
    private static final class Sync extends AbstractQueuedSynchronizer {
        
        Sync(int count) {
            setState(count);  // 初始化计数器
        }
        
        /**
         * 获取共享锁(等待计数器为0)
         */
        protected int tryAcquireShared(int acquires) {
            return (getState() == 0) ? 1 : -1;
        }
        
        /**
         * 释放共享锁(计数器减1)
         */
        protected boolean tryReleaseShared(int releases) {
            for (;;) {
                int c = getState();
                if (c == 0) {
                    return false;
                }
                int nextc = c - 1;
                if (compareAndSetState(c, nextc)) {
                    return nextc == 0;  // 计数器为0时返回true
                }
            }
        }
    }
    
    private final Sync sync;
    
    public CountDownLatch(int count) {
        if (count < 0) {
            throw new IllegalArgumentException("count < 0");
        }
        this.sync = new Sync(count);
    }
    
    /**
     * 等待计数器减到0
     */
    public void await() throws InterruptedException {
        sync.acquireSharedInterruptibly(1);
    }
    
    /**
     * 计数器减1
     */
    public void countDown() {
        sync.releaseShared(1);
    }
}

7.3 CountDownLatch 使用示例

/**
 * CountDownLatch 实际应用示例
 */
@Service
@Slf4j
public class CountDownLatchExample {
    
    /**
     * 场景1: 等待多个任务完成
     */
    public void waitForTasks() throws InterruptedException {
        int taskCount = 10;
        CountDownLatch latch = new CountDownLatch(taskCount);
        ExecutorService executor = Executors.newFixedThreadPool(taskCount);
        
        for (int i = 0; i < taskCount; i++) {
            final int taskId = i;
            executor.submit(() -> {
                try {
                    // 执行任务
                    doTask(taskId);
                } finally {
                    latch.countDown();  // 任务完成,计数器减1
                }
            });
        }
        
        latch.await();  // 等待所有任务完成
        log.info("All tasks completed");
    }
    
    /**
     * 场景2: 主线程等待子线程初始化
     */
    public void waitForInitialization() throws InterruptedException {
        CountDownLatch initLatch = new CountDownLatch(3);
        
        // 启动3个子线程进行初始化
        for (int i = 0; i < 3; i++) {
            new Thread(() -> {
                try {
                    initialize();
                } finally {
                    initLatch.countDown();
                }
            }).start();
        }
        
        initLatch.await();  // 主线程等待初始化完成
        log.info("Initialization completed");
    }
    
    /**
     * 场景3: 并行计算后汇总
     */
    public int parallelCompute(List<Integer> data) throws InterruptedException {
        int threadCount = Runtime.getRuntime().availableProcessors();
        CountDownLatch latch = new CountDownLatch(threadCount);
        AtomicInteger result = new AtomicInteger(0);
        
        int chunkSize = data.size() / threadCount;
        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        
        for (int i = 0; i < threadCount; i++) {
            final int start = i * chunkSize;
            final int end = (i == threadCount - 1) ? data.size() : (i + 1) * chunkSize;
            
            executor.submit(() -> {
                try {
                    int sum = 0;
                    for (int j = start; j < end; j++) {
                        sum += data.get(j);
                    }
                    result.addAndGet(sum);
                } finally {
                    latch.countDown();
                }
            });
        }
        
        latch.await();
        return result.get();
    }
    
    private void doTask(int taskId) {
        // 任务逻辑
    }
    
    private void initialize() {
        // 初始化逻辑
    }
}

八、CyclicBarrier 循环屏障

8.1 CyclicBarrier 基本概念

CyclicBarrier 循环屏障:

┌───────────────────────────────────────────────────────┐
│                   循环屏障原理                         │
├───────────────────────────────────────────────────────┤
│                                                       │
│  概念:                                                │
│    - 多个线程互相等待,到达同步点后继续执行              │
│    - 可以重复使用(cyclic)                            │
│    - 支持屏障动作(barrier action)                    │
│                                                       │
│  与CountDownLatch的区别:                              │
│    - CountDownLatch: 一个或多个线程等待其他线程         │
│    - CyclicBarrier: 多个线程互相等待                   │
│    - CountDownLatch: 一次性使用                       │
│    - CyclicBarrier: 可重复使用                        │
│                                                      │
│  应用场景:                                           │
│    - 分阶段任务(多阶段并行计算)                      │
│    - 数据分片处理后汇总                               │
│    - 多线程测试                                      │
└─────────────────────────────────────────────────────┘

8.2 CyclicBarrier 实现原理

/**
 * CyclicBarrier 核心实现
 */
public class CyclicBarrier {
    
    private static class Generation {
        boolean broken = false;
    }
    
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition trip = lock.newCondition();
    private final int parties;  // 参与的线程数
    private final Runnable barrierCommand;  // 屏障动作
    private Generation generation = new Generation();
    private int count;  // 当前等待的线程数
    
    public CyclicBarrier(int parties, Runnable barrierAction) {
        if (parties <= 0) {
            throw new IllegalArgumentException();
        }
        this.parties = parties;
        this.count = parties;
        this.barrierCommand = barrierAction;
    }
    
    /**
     * 等待到达屏障
     */
    public int await() throws InterruptedException, BrokenBarrierException {
        try {
            return dowait(false, 0L);
        } catch (TimeoutException toe) {
            throw new Error(toe);
        }
    }
    
    private int dowait(boolean timed, long nanos)
            throws InterruptedException, BrokenBarrierException, TimeoutException {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            final Generation g = generation;
            
            if (g.broken) {
                throw new BrokenBarrierException();
            }
            
            if (Thread.interrupted()) {
                breakBarrier();
                throw new InterruptedException();
            }
            
            int index = --count;
            if (index == 0) {
                // 最后一个线程到达,执行屏障动作
                boolean ranAction = false;
                try {
                    final Runnable command = barrierCommand;
                    if (command != null) {
                        command.run();
                    }
                    ranAction = true;
                    // 重置屏障,唤醒所有等待的线程
                    nextGeneration();
                    return 0;
                } finally {
                    if (!ranAction) {
                        breakBarrier();
                    }
                }
            }
            
            // 等待其他线程到达
            for (;;) {
                try {
                    if (!timed) {
                        trip.await();
                    } else if (nanos > 0L) {
                        nanos = trip.awaitNanos(nanos);
                    }
                } catch (InterruptedException ie) {
                    if (g == generation && !g.broken) {
                        breakBarrier();
                        throw ie;
                    } else {
                        Thread.currentThread().interrupt();
                    }
                }
                
                if (g.broken) {
                    throw new BrokenBarrierException();
                }
                
                if (g != generation) {
                    return index;
                }
                
                if (timed && nanos <= 0L) {
                    breakBarrier();
                    throw new TimeoutException();
                }
            }
        } finally {
            lock.unlock();
        }
    }
    
    /**
     * 重置屏障
     */
    private void nextGeneration() {
        trip.signalAll();
        count = parties;
        generation = new Generation();
    }
    
    /**
     * 破坏屏障
     */
    private void breakBarrier() {
        generation.broken = true;
        count = parties;
        trip.signalAll();
    }
}

8.3 CyclicBarrier 使用示例

/**
 * CyclicBarrier 实际应用示例
 */
@Service
@Slf4j
public class CyclicBarrierExample {
    
    /**
     * 场景1: 分阶段并行计算
     */
    public void phasedComputation() throws BrokenBarrierException, InterruptedException {
        int threadCount = 4;
        CyclicBarrier barrier = new CyclicBarrier(threadCount, () -> {
            log.info("All threads reached barrier, continue...");
        });
        
        ExecutorService executor = Executors.newFixedThreadPool(threadCount);
        
        for (int i = 0; i < threadCount; i++) {
            final int threadId = i;
            executor.submit(() -> {
                try {
                    // 阶段1
                    log.info("Thread {} phase 1", threadId);
                    barrier.await();
                    
                    // 阶段2
                    log.info("Thread {} phase 2", threadId);
                    barrier.await();
                    
                    // 阶段3
                    log.info("Thread {} phase 3", threadId);
                    barrier.await();
                } catch (InterruptedException | BrokenBarrierException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
    }
    
    /**
     * 场景2: 数据分片处理
     */
    public void dataChunkProcessing(List<Integer> data) throws BrokenBarrierException, InterruptedException {
        int chunkCount = 4;
        CyclicBarrier barrier = new CyclicBarrier(chunkCount + 1);  // +1 for main thread
        List<List<Integer>> chunks = partition(data, chunkCount);
        AtomicInteger totalSum = new AtomicInteger(0);
        
        ExecutorService executor = Executors.newFixedThreadPool(chunkCount);
        
        for (List<Integer> chunk : chunks) {
            executor.submit(() -> {
                try {
                    int sum = chunk.stream().mapToInt(Integer::intValue).sum();
                    totalSum.addAndGet(sum);
                    barrier.await();  // 等待所有分片处理完成
                } catch (InterruptedException | BrokenBarrierException e) {
                    Thread.currentThread().interrupt();
                }
            });
        }
        
        barrier.await();  // 主线程等待
        log.info("Total sum: {}", totalSum.get());
    }
    
    private List<List<Integer>> partition(List<Integer> data, int chunks) {
        // 数据分片逻辑
        return null;
    }
}

九、Phaser 阶段器

9.1 Phaser 基本概念

Phaser 阶段器(JDK 7+):

┌──────────────────────────────────────────────────┐
│                   阶段器特性                      │
├──────────────────────────────────────────────────┤
│                                                  │
│  概念:                                           │
│    - 可重用的同步屏障                             │
│    - 支持分阶段同步                               │
│    - 支持动态注册和注销线程                        │
│                                                  │
│  优势:                                           │
│    - 比CyclicBarrier更灵活                       │
    - 支持动态调整参与线程数                        │
    - 支持分层结构                                 │
│                                                 │
│  应用场景:                                       │
│    - 复杂的分阶段任务                             │
│    - 动态线程同步                                 │
│    - 游戏开发(多阶段游戏逻辑)                    │
└──────────────────────────────────────────────────┘

9.2 Phaser 使用示例

/**
 * Phaser 实际应用示例
 */
@Service
@Slf4j
public class PhaserExample {
    
    /**
     * 场景1: 分阶段任务
     */
    public void phasedTask() {
        Phaser phaser = new Phaser(3);  // 3个参与线程
        
        ExecutorService executor = Executors.newFixedThreadPool(3);
        
        for (int i = 0; i < 3; i++) {
            final int taskId = i;
            executor.submit(() -> {
                // 阶段0
                log.info("Task {} phase 0", taskId);
                phaser.arriveAndAwaitAdvance();
                
                // 阶段1
                log.info("Task {} phase 1", taskId);
                phaser.arriveAndAwaitAdvance();
                
                // 阶段2
                log.info("Task {} phase 2", taskId);
                phaser.arriveAndAwaitAdvance();
            });
        }
    }
    
    /**
     * 场景2: 动态注册线程
     */
    public void dynamicRegistration() {
        Phaser phaser = new Phaser(1);  // 主线程注册
        
        for (int i = 0; i < 3; i++) {
            phaser.register();  // 动态注册
            final int taskId = i;
            new Thread(() -> {
                log.info("Task {} started", taskId);
                phaser.arriveAndAwaitAdvance();
                log.info("Task {} completed", taskId);
                phaser.arriveAndDeregister();  // 注销
            }).start();
        }
        
        phaser.arriveAndAwaitAdvance();  // 等待所有任务完成
    }
    
    /**
     * 场景3: 分层Phaser
     */
    public void hierarchicalPhaser() {
        Phaser rootPhaser = new Phaser(3);
        
        // 创建子Phaser
        Phaser childPhaser1 = new Phaser(rootPhaser, 2);
        Phaser childPhaser2 = new Phaser(rootPhaser, 2);
        
        // 使用子Phaser
        ExecutorService executor = Executors.newFixedThreadPool(4);
        
        executor.submit(() -> {
            childPhaser1.arriveAndAwaitAdvance();
            log.info("Child task 1 completed");
        });
        
        executor.submit(() -> {
            childPhaser1.arriveAndAwaitAdvance();
            log.info("Child task 2 completed");
        });
        
        executor.submit(() -> {
            childPhaser2.arriveAndAwaitAdvance();
            log.info("Child task 3 completed");
        });
        
        executor.submit(() -> {
            childPhaser2.arriveAndAwaitAdvance();
            log.info("Child task 4 completed");
        });
    }
}

十、LockSupport 锁支持

10.1 LockSupport 基本概念

LockSupport 锁支持:

┌──────────────────────────────────────────────────┐
│                   LockSupport 特点               │
├─────────────────────────────────────────────────┤
│                                                  │
│  功能:                                           │
│    - 线程阻塞和唤醒的基础工具                      │
│    - 每个线程都有一个许可(permit)                │
│    - park(): 阻塞线程(如果许可不可用)            │
│    - unpark(): 唤醒线程(使许可可用)              │
│                                                  │
│  优势:                                           │
│    - 更精确的线程控制                              │
│    - 不会抛出InterruptedException                 │
│    - 支持先unpark后park(许可可以提前发放)         │
│                                                  │
│  应用:                                           │
│    - AQS的底层实现                                │
│    - 自定义同步工具                               │
└──────────────────────────────────────────────────┘

10.2 LockSupport 使用示例

/**
 * LockSupport 使用示例
 */
public class LockSupportExample {
    
    /**
     * 基本用法
     */
    public void basicUsage() {
        Thread thread = new Thread(() -> {
            System.out.println("Thread waiting...");
            LockSupport.park();  // 阻塞线程
            System.out.println("Thread resumed");
        });
        
        thread.start();
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        
        LockSupport.unpark(thread);  // 唤醒线程
    }
    
    /**
     * 先unpark后park(许可可以提前发放)
     */
    public void unparkBeforePark() {
        Thread thread = new Thread(() -> {
            try {
                Thread.sleep(1000);  // 延迟1秒
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
            System.out.println("Thread trying to park...");
            LockSupport.park();  // 不会阻塞,因为许可已经可用
            System.out.println("Thread continued");
        });
        
        thread.start();
        LockSupport.unpark(thread);  // 先发放许可
    }
    
    /**
     * 自定义锁实现(基于LockSupport)
     */
    public class CustomLock {
        private volatile Thread owner;
        private final Queue<Thread> waitQueue = new ConcurrentLinkedQueue<>();
        
        public void lock() {
            Thread currentThread = Thread.currentThread();
            
            if (owner == null && compareAndSetOwner(null, currentThread)) {
                return;  // 获取锁成功
            }
            
            // 获取锁失败,加入等待队列
            waitQueue.offer(currentThread);
            
            // 自旋等待
            while (owner != currentThread) {
                LockSupport.park();  // 阻塞
            }
        }
        
        public void unlock() {
            Thread currentThread = Thread.currentThread();
            
            if (owner != currentThread) {
                throw new IllegalMonitorStateException();
            }
            
            owner = null;
            
            // 唤醒等待队列中的线程
            Thread nextThread = waitQueue.poll();
            if (nextThread != null) {
                LockSupport.unpark(nextThread);
            }
        }
        
        private boolean compareAndSetOwner(Thread expect, Thread update) {
            // CAS操作
            return false;
        }
    }
}

十一、原子类(Atomic Classes)

11.1 原子类体系

Java原子类体系:

┌───────────────────────────────────────────────────────┐
│                   原子类分类                           │
├───────────────────────────────────────────────────────┤
│                                                       │
│  1. 基本类型原子类:                                    │
│     - AtomicInteger                                   │
│     - AtomicLong                                      │
│     - AtomicBoolean                                   │
│                                                       │
│  2. 引用类型原子类:                                    │
│     - AtomicReference                                 │
│     - AtomicStampedReference(带版本号)               │
│     - AtomicMarkableReference(带标记位)              │
│                                                       │
│  3. 数组类型原子类:                                    │
│     - AtomicIntegerArray                              │
│     - AtomicLongArray                                 │
│     - AtomicReferenceArray                            │
│                                                       │
│  4. 字段更新器:                                        │
│     - AtomicIntegerFieldUpdater                       │
│     - AtomicLongFieldUpdater                          │
│     - AtomicReferenceFieldUpdater                     │
│                                                       │
│  5. 累加器(JDK 8+):                                  │
│     - LongAdder                                       │
│     - DoubleAdder                                     │
│     - LongAccumulator                                 │
│     - DoubleAccumulator                               │
└───────────────────────────────────────────────────────┘

11.2 AtomicInteger 深度解析

/**
 * AtomicInteger 核心实现原理
 */
public class AtomicInteger extends Number implements java.io.Serializable {
    
    private static final Unsafe unsafe = Unsafe.getUnsafe();
    private static final long valueOffset;
    
    static {
        try {
            valueOffset = unsafe.objectFieldOffset(
                AtomicInteger.class.getDeclaredField("value"));
        } catch (Exception ex) {
            throw new Error(ex);
        }
    }
    
    private volatile int value;
    
    /**
     * CAS操作
     */
    public final boolean compareAndSet(int expect, int update) {
        return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
    }
    
    /**
     * 获取并增加
     */
    public final int getAndIncrement() {
        return unsafe.getAndAddInt(this, valueOffset, 1);
    }
    
    /**
     * 增加并获取
     */
    public final int incrementAndGet() {
        return unsafe.getAndAddInt(this, valueOffset, 1) + 1;
    }
    
    /**
     * 原子更新(函数式)
     */
    public final int updateAndGet(IntUnaryOperator updateFunction) {
        int prev, next;
        do {
            prev = get();
            next = updateFunction.applyAsInt(prev);
        } while (!compareAndSet(prev, next));
        return next;
    }
}

11.3 LongAdder 高性能累加器

/**
 * LongAdder 高性能累加器(JDK 8+)
 * 
 * 原理: 分段累加,减少CAS竞争
 */
public class LongAdderExample {
    
    /**
     * LongAdder vs AtomicLong 性能对比
     */
    public void performanceComparison() {
        AtomicLong atomicLong = new AtomicLong(0);
        LongAdder longAdder = new LongAdder();
        
        int threadCount = 10;
        int operations = 1000000;
        
        // AtomicLong测试
        long start = System.currentTimeMillis();
        ExecutorService executor1 = Executors.newFixedThreadPool(threadCount);
        for (int i = 0; i < threadCount; i++) {
            executor1.submit(() -> {
                for (int j = 0; j < operations; j++) {
                    atomicLong.incrementAndGet();
                }
            });
        }
        executor1.shutdown();
        try {
            executor1.awaitTermination(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        long atomicTime = System.currentTimeMillis() - start;
        
        // LongAdder测试
        start = System.currentTimeMillis();
        ExecutorService executor2 = Executors.newFixedThreadPool(threadCount);
        for (int i = 0; i < threadCount; i++) {
            executor2.submit(() -> {
                for (int j = 0; j < operations; j++) {
                    longAdder.increment();
                }
            });
        }
        executor2.shutdown();
        try {
            executor2.awaitTermination(1, TimeUnit.MINUTES);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        long adderTime = System.currentTimeMillis() - start;
        
        System.out.println("AtomicLong time: " + atomicTime + "ms");
        System.out.println("LongAdder time: " + adderTime + "ms");
        // LongAdder在高并发下性能通常优于AtomicLong
    }
    
    /**
     * LongAdder 实现原理(简化版)
     */
    public class LongAdderCore {
        private volatile Cell[] cells;  // 分段数组
        private volatile long base;     // 基础值
        
        /**
         * 累加
         */
        public void increment() {
            Cell[] as = cells;
            Cell a;
            long b = base, v;
            
            if (as != null && (a = as[getProbe() & (as.length - 1)]) != null) {
                // 使用分段累加
                if (!a.cas(v = a.value, v + 1)) {
                    longAccumulate(1L, null, true);
                }
            } else if (casBase(b = base, b + 1)) {
                // 使用base累加
                return;
            } else {
                longAccumulate(1L, null, false);
            }
        }
        
        /**
         * 获取总和
         */
        public long sum() {
            Cell[] as = cells;
            long sum = base;
            if (as != null) {
                for (Cell a : as) {
                    if (a != null) {
                        sum += a.value;
                    }
                }
            }
            return sum;
        }
    }
}

十二、锁的性能对比

12.1 性能测试代码

/**
 * 锁性能基准测试(JMH)
 */
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
@State(Scope.Benchmark)
public class LockPerformanceBenchmark {
    
    private int counter = 0;
    private final Object syncLock = new Object();
    private final ReentrantLock reentrantLock = new ReentrantLock();
    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final StampedLock stampedLock = new StampedLock();
    private final AtomicInteger atomicInt = new AtomicInteger(0);
    
    /**
     * synchronized性能
     */
    @Benchmark
    public void testSynchronized() {
        synchronized (syncLock) {
            counter++;
        }
    }
    
    /**
     * ReentrantLock性能
     */
    @Benchmark
    public void testReentrantLock() {
        reentrantLock.lock();
        try {
            counter++;
        } finally {
            reentrantLock.unlock();
        }
    }
    
    /**
     * ReentrantReadWriteLock写锁性能
     */
    @Benchmark
    public void testReadWriteLockWrite() {
        rwLock.writeLock().lock();
        try {
            counter++;
        } finally {
            rwLock.writeLock().unlock();
        }
    }
    
    /**
     * StampedLock写锁性能
     */
    @Benchmark
    public void testStampedLockWrite() {
        long stamp = stampedLock.writeLock();
        try {
            counter++;
        } finally {
            stampedLock.unlockWrite(stamp);
        }
    }
    
    /**
     * CAS操作性能
     */
    @Benchmark
    public void testCAS() {
        atomicInt.incrementAndGet();
    }
}

12.2 性能测试结果

性能测试结果(单线程,1000万次操作):

┌────────────────────────────────────────────────────────┐
│                   操作耗时(毫秒)                      │
├──────────────┬──────────┬──────────┬───────────────────┤
│ 锁类型        │ 无竞争    │ 低竞争    │ 高竞争           │
├──────────────┼──────────┼──────────┼───────────────────┤
│ synchronized │ ~100ms   │ ~200ms   │ ~500ms            │
│ ReentrantLock│ ~150ms   │ ~250ms   │ ~600ms            │
│ ReadWriteLock│ ~200ms   │ ~300ms   │ ~700ms            │
│ StampedLock  │ ~180ms   │ ~280ms   │ ~650ms            │
│ CAS          │ ~50ms    │ ~100ms   │ ~300ms(自旋)     │
└──────────────┴──────────┴──────────┴───────────────────┘

性能分析:

1. 无竞争场景:
   - CAS最快(~50ms),无锁操作
   - synchronized次之(~100ms),偏向锁优化
   - ReentrantLock较慢(~150ms),方法调用开销

2. 低竞争场景:
   - CAS仍然最快(~100ms)
   - synchronized中等(~200ms),轻量级锁
   - ReentrantLock较慢(~250ms)

3. 高竞争场景:
   - CAS性能下降(~300ms),大量自旋
   - synchronized性能下降(~500ms),重量级锁
   - ReentrantLock性能下降(~600ms),线程阻塞

12.3 读写锁性能对比

读写锁性能对比(读多写少场景,读:写 = 10:1):

┌────────────────────────────────────────────────────┐
│                   性能对比                          │
├──────────────┬──────────┬──────────────────────────┤
│ 锁类型        │ QPS      │ 说明                     │
├──────────────┼──────────┼──────────────────────────┤
│ synchronized │ 1,000    │ 所有操作串行              │
│ ReentrantLock│ 1,000    │ 所有操作串行              │
│ ReadWriteLock│ 5,000    │ 读操作并发(10倍提升)     │
│ StampedLock  │ 8,000    │ 乐观读性能更高(16倍提升) │
└──────────────┴──────────┴──────────────────────────┘

十三、最佳实践与选择指南

13.1 锁选择决策树

锁选择决策树:

开始
  │
  ├─ 是否需要跨进程/跨服务器?
  │   ├─ 是 → 使用分布式锁(Redis/ZooKeeper/etcd)
  │   └─ 否 → 继续
  │
  ├─ 读多写少?
  │   ├─ 是 → 使用读写锁(ReentrantReadWriteLock/StampedLock)
  │   └─ 否 → 继续
  │
  ├─ 需要高级特性(可中断、超时、条件变量)?
  │   ├─ 是 → 使用ReentrantLock
  │   └─ 否 → 继续
  │
  ├─ 需要限制并发数?
  │   ├─ 是 → 使用Semaphore
  │   └─ 否 → 继续
  │
  ├─ 需要等待多个任务完成?
  │   ├─ 是 → 使用CountDownLatch
  │   └─ 否 → 继续
  │
  ├─ 需要分阶段同步?
  │   ├─ 是 → 使用CyclicBarrier/Phaser
  │   └─ 否 → 继续
  │
  ├─ 只需要原子操作?
  │   ├─ 是 → 使用原子类(AtomicInteger等)
  │   └─ 否 → 使用synchronized

13.2 性能优化建议

性能优化建议:

1. 减少锁的持有时间
   ✅ 只锁必要的代码块
   ❌ 不要在锁内执行耗时操作

2. 减小锁的粒度
   ✅ 使用细粒度锁
   ❌ 避免粗粒度锁

3. 减少锁的竞争
   ✅ 使用分段锁
   ✅ 使用读写锁(读多写少)
   ✅ 使用无锁数据结构

4. 合理选择锁类型
   ✅ 读多写少 → 读写锁
   ✅ 只需要原子操作 → 原子类
   ✅ 需要高级特性 → ReentrantLock
   ✅ 简单场景 → synchronized

5. 避免死锁
   ✅ 统一锁的获取顺序
   ✅ 设置锁超时时间
   ✅ 使用tryLock()

13.3 常见陷阱与避免方法

常见陷阱:

1. 锁泄漏
   ❌ 异常时未释放锁
   ✅ 使用try-finally确保释放

2. 死锁
   ❌ 多个锁的获取顺序不一致
   ✅ 统一锁的获取顺序

3. 活锁
   ❌ 线程互相谦让
   ✅ 引入随机等待时间

4. 过度使用锁
   ❌ 所有操作都加锁
   ✅ 只在必要时加锁

5. 锁的粒度不当
   ❌ 锁整个方法
   ✅ 只锁必要的代码块

6. 忽略ABA问题
   ❌ 直接使用CAS
   ✅ 使用版本号或AtomicStampedReference

总结

Java锁体系总结

Java锁体系完整总结:

┌─────────────────────────────────────────────────────┐
│                   锁类型与适用场景                   │
├──────────────┬──────────┬───────────────────────────┤
│ 锁类型        │ 性能      │ 适用场景                  │
├──────────────┼──────────┼───────────────────────────┤
│ synchronized │ ⭐⭐⭐⭐  │ 通用场景,简单易用       │
│ ReentrantLock│ ⭐⭐⭐   │ 需要高级特性              │
│ ReadWriteLock│ ⭐⭐⭐⭐  │ 读多写少                │
│ StampedLock  │ ⭐⭐⭐⭐⭐│ 读多写少(JDK8+)       │
│ Semaphore    │ ⭐⭐⭐   │ 限流、资源控制            │
│ CountDownLatch│ ⭐⭐⭐⭐ │ 等待多个任务完成         │
│ CyclicBarrier│ ⭐⭐⭐   │ 分阶段同步               │
│ Phaser       │ ⭐⭐⭐   │ 复杂分阶段同步            │
│ AtomicInteger│ ⭐⭐⭐⭐⭐│ 计数器、状态标志         │
└──────────────┴──────────┴────────────────────────────┘

核心要点

✅ 根据场景选择合适的锁类型
✅ 减少锁的持有时间和粒度
✅ 避免死锁和锁泄漏
✅ 合理使用读写锁优化性能
✅ 在高并发场景下考虑无锁编程
✅ 监控锁的使用情况,及时优化

参考资源:

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值