Java 线程同步-04:lock 机制

前言

Java的Lock机制是Java并发编程(JDK 1.5+)中用于控制多个线程访问共享资源的核心工具。它位于java.util.concurrent.locks包下,提供了比传统的synchronized关键字更灵活、更强大的锁定操作。

本文主要介绍以 ReentrantLockReentrantReadWriteLock 为代表的lock机制,文章内容包含一下几个:Java Lock 类继承关系、Lock 使用代码示例、Lock 原理。

类结构

Java的lock机制源头可以从Lock接口说起,这是lock机制的抽象类,规定了锁的相关协议,它定义了锁的获取和释放方法。相比于synchronized(隐式获取/释放锁),Lock需要显式地获取和释放锁。

Lock接口核心方法:

java 复制代码
public interface Lock {
    // 1. 基本锁操作
    void lock();
    void unlock();
    
    // 2. 可中断锁
    void lockInterruptibly() throws InterruptedException;
    
    // 3. 尝试获取锁
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    
    // 4. 条件变量
    Condition newCondition();
}

Java同步机制里面涉及的接口层主要有下面三个核心接口:

  1. Lock 接口 - 所有锁的顶级接口,定义了 lock()、unlock() 等基本方法
  2. ReadWriteLock 接口 - 读写锁接口,定义了读锁和写锁的获取方法
  3. Condition 接口 - 条件变量接口,用于线程间的等待/通知机制

对上面几个接口类常用的主要有几个实现类:

  1. ReentrantLock:实现了 Lock 接口内部包含 Sync 同步器
  2. ReentrantReadWriteLock:实现了 ReadWriteLock 接口 内部包含 Sync、ReadLock、WriteLock几个内部类
  3. ConditionObject:实现了 Condition 接口,是 AQS 的内部类

简化版继承结构类图UML:

flowchart TD %% 接口层 Lock[Lock接口] --> RL[ReentrantLock] Lock --> RLock[ReadLock] Lock --> WLock[WriteLock] RWL[ReadWriteLock接口] --> RWLImpl[ReentrantReadWriteLock] RWLImpl --> RLock RWLImpl --> WLock Cond[Condition接口] --> CondObj[ConditionObject] %% AQS层 AQS[AQS] --> Sync[Sync] AQS --> RWSync[ReadWriteSync] Sync --> FSync[FairSync] Sync --> NFSync[NonfairSync] %% 组合关系 RL -.-> Sync RWLImpl -.-> RWSync RLock -.-> RWSync WLock -.-> RWSync Sync -.-> CondObj RWSync -.-> CondObj style Lock fill:#f9f style RWL fill:#f9f style Cond fill:#f9f style AQS fill:#ccf style RL fill:#cfc style RWLImpl fill:#cfc style RLock fill:#cfc style WLock fill:#cfc

详细版继承结构类图UML:

classDiagram %% ========== 核心接口和抽象类 ========== class Lock { <<interface>> +lock() void +lockInterruptibly() void +tryLock() boolean +tryLock(long, TimeUnit) boolean +unlock() void +newCondition() Condition } class ReadWriteLock { <<interface>> +readLock() Lock +writeLock() Lock } class Condition { <<interface>> +await() void +await(long, TimeUnit) boolean +awaitNanos(long) long +awaitUninterruptibly() void +signal() void +signalAll() void } class AbstractQueuedSynchronizer { <<abstract>> #state : int #head : Node #tail : Node #getState() int #setState(int) void #compareAndSetState(int, int) boolean #tryAcquire(int) boolean #tryRelease(int) boolean #tryAcquireShared(int) int #tryReleaseShared(int) boolean #isHeldExclusively() boolean #acquire(int) void #acquireInterruptibly(int) void #release(int) boolean #acquireShared(int) void #releaseShared(int) boolean } class AbstractOwnableSynchronizer { <<abstract>> #exclusiveOwnerThread : Thread #getExclusiveOwnerThread() Thread #setExclusiveOwnerThread(Thread) void } %% ========== ReentrantLock 相关 ========== class ReentrantLock { -sync : Sync +ReentrantLock() +ReentrantLock(boolean) +lock() void +lockInterruptibly() void +tryLock() boolean +tryLock(long, TimeUnit) boolean +unlock() void +isFair() boolean +isLocked() boolean +isHeldByCurrentThread() boolean +getHoldCount() int +getQueueLength() int +hasQueuedThreads() boolean +newCondition() Condition } class Sync { <<abstract>> +lock() void +nonfairTryAcquire(int) boolean +tryRelease(int) boolean +isHeldExclusively() boolean +newCondition() ConditionObject } class FairSync { +lock() void #tryAcquire(int) boolean } class NonfairSync { +lock() void #tryAcquire(int) boolean } %% ========== ReentrantReadWriteLock 相关 ========== class ReentrantReadWriteLock { -sync : Sync -readerLock : ReadLock -writerLock : WriteLock +ReentrantReadWriteLock() +ReentrantReadWriteLock(boolean) +readLock() Lock +writeLock() Lock +isFair() boolean +getReadLockCount() int +isWriteLocked() boolean +isWriteLockedByCurrentThread() boolean +getWriteHoldCount() int +getReadHoldCount() int } class ReadLock { -sync : Sync +lock() void +lockInterruptibly() void +tryLock() boolean +tryLock(long, TimeUnit) boolean +unlock() void +newCondition() Condition } class WriteLock { -sync : Sync +lock() void +lockInterruptibly() void +tryLock() boolean +tryLock(long, TimeUnit) boolean +unlock() void +newCondition() Condition +isHeldByCurrentThread() boolean +getHoldCount() int } class Sync { <<abstract>> +tryAcquire(int) boolean +tryRelease(int) boolean +tryAcquireShared(int) int +tryReleaseShared(int) boolean +isHeldExclusively() boolean +newCondition() ConditionObject } class FairSync { #writerShouldBlock() boolean #readerShouldBlock() boolean } class NonfairSync { #writerShouldBlock() boolean #readerShouldBlock() boolean } %% ========== StampedLock 相关 ========== class StampedLock { +StampedLock() +readLock() long +tryReadLock() long +tryReadLock(long, TimeUnit) long +readLockInterruptibly() long +writeLock() long +tryWriteLock() long +tryWriteLock(long, TimeUnit) long +writeLockInterruptibly() long +tryOptimisticRead() long +validate(long) boolean +unlock(long) void +unlockRead(long) void +unlockWrite(long) void +tryConvertToWriteLock(long) long +tryConvertToReadLock(long) long +tryConvertToOptimisticRead(long) long +isReadLocked() boolean +isWriteLocked() boolean +getReadLockCount() int } %% ========== AQS 内部类 ========== class Node { <<static>> +SHARED : Node +EXCLUSIVE : Node +CANCELLED : int +SIGNAL : int +CONDITION : int +PROPAGATE : int +waitStatus : int +prev : Node +next : Node +thread : Thread +nextWaiter : Node +isShared() boolean +predecessor() Node } class ConditionObject { +firstWaiter : Node +lastWaiter : Node +await() void +await(long, TimeUnit) boolean +awaitNanos(long) long +awaitUninterruptibly() void +signal() void +signalAll() void +hasWaiters(ConditionObject) boolean +getWaitQueueLength(ConditionObject) int +getWaitingThreads(ConditionObject) Collection~Thread~ } %% ========== 其他相关类 ========== class LockSupport { <<final>> +park() void +park(Object) void +parkNanos(long) void +parkUntil(long) void +unpark(Thread) void +getBlocker(Thread) Object } class TimeUnit { <<enum>> +NANOSECONDS +MICROSECONDS +MILLISECONDS +SECONDS +MINUTES +HOURS +DAYS +toNanos(long) long +toMicros(long) long +toMillis(long) long +toSeconds(long) long +toMinutes(long) long +toHours(long) long +toDays(long) long } %% ========== 继承关系 ========== Lock <|.. ReentrantLock Lock <|.. ReadLock Lock <|.. WriteLock Condition <|.. ConditionObject ReadWriteLock <|.. ReentrantReadWriteLock AbstractOwnableSynchronizer <|-- AbstractQueuedSynchronizer AbstractQueuedSynchronizer <|-- ReentrantLock.Sync AbstractQueuedSynchronizer <|-- ReentrantReadWriteLock.Sync ReentrantLock.Sync <|-- ReentrantLock.FairSync ReentrantLock.Sync <|-- ReentrantLock.NonfairSync ReentrantReadWriteLock.Sync <|-- ReentrantReadWriteLock.FairSync ReentrantReadWriteLock.Sync <|-- ReentrantReadWriteLock.NonfairSync %% ========== 关联关系 ========== ReentrantLock *-- "1" Sync : contains ReentrantReadWriteLock *-- "1" Sync : contains ReentrantReadWriteLock *-- "1" ReadLock : contains ReentrantReadWriteLock *-- "1" WriteLock : contains ReadLock *-- "1" Sync : uses WriteLock *-- "1" Sync : uses Sync *-- "1" ConditionObject : creates AbstractQueuedSynchronizer *-- "0..*" Node : manages ConditionObject *-- "0..*" Node : manages %% ========== 依赖关系 ========== ReentrantLock ..> TimeUnit : uses in tryLock() ReadLock ..> TimeUnit : uses in tryLock() WriteLock ..> TimeUnit : uses in tryLock() ConditionObject ..> TimeUnit : uses in await() LockSupport ..> Thread : manages AbstractQueuedSynchronizer ..> LockSupport : uses ConditionObject ..> LockSupport : uses

使用方式

ReentrantLock 使用示例

java 复制代码
package concurrent;

import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class ReentrantLockDemo {
    private final ReentrantLock lock = new ReentrantLock();
    private int counter = 0;

    // 1. 基本 lock() 和 unlock()
    public void basicLock() {
        lock.lock();
        try {
            counter++;
            System.out.println(Thread.currentThread().getName() +
                    " [basicLock] 计数器: " + counter);
            Thread.sleep(100); // 模拟工作
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
        }
    }

    /** 持锁一段时间,用于配合 lockInterruptibly 演示 */
    public void holdLock(long millis) {
        lock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " 持有锁 " + millis + "ms");
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            lock.unlock();
            System.out.println(Thread.currentThread().getName() + " 释放锁");
        }
    }

    // 2. tryLock(timeout) - 超时尝试获取锁
    public void tryLockWithTimeout() {
        try {
            if (lock.tryLock(500, TimeUnit.MILLISECONDS)) {
                try {
                    System.out.println(Thread.currentThread().getName() +
                            " [tryLockTimeout] 在500ms内获取成功");
                    Thread.sleep(200); // 模拟工作
                } finally {
                    lock.unlock();
                }
            } else {
                System.out.println(Thread.currentThread().getName() +
                        " [tryLockTimeout] 获取超时");
            }
        } catch (InterruptedException e) {
            System.out.println(Thread.currentThread().getName() +
                    " [tryLockTimeout] 被中断");
            Thread.currentThread().interrupt();
        }
    }

    // 3. lockInterruptibly() - 可中断锁(在等待锁的过程中可被 interrupt 并抛出 InterruptedException)
    public void lockInterruptiblyExample() throws InterruptedException {
        System.out.println(Thread.currentThread().getName() + " 尝试 lockInterruptibly(),若锁被占用将阻塞等待...");
        lock.lockInterruptibly(); // 阻塞等待期间若被 interrupt,会抛出 InterruptedException
        try {
            System.out.println(Thread.currentThread().getName() + " 获取锁成功,执行业务");
            Thread.sleep(500);
        } finally {
            if (lock.isHeldByCurrentThread()) {
                lock.unlock();
                System.out.println(Thread.currentThread().getName() + " 释放锁");
            }
        }
    }

    // 运行 ReentrantLock 所有示例
    public static void main(String[] args) throws Exception {
        System.out.println("\n========== ReentrantLock 示例开始 ==========");

        ReentrantLockDemo reentrantDemo = new ReentrantLockDemo();
        // 1. 基本 lock() 示例
        System.out.println("\n1. 基本 lock() 示例:");
        Thread t1 = new Thread(() -> reentrantDemo.basicLock(), "Thread-1");
        Thread t2 = new Thread(() -> reentrantDemo.basicLock(), "Thread-2");
        t1.start();
        t2.start();
        t1.join();
        t2.join();

        // 2. tryLock(timeout) 示例
        System.out.println("\n2. tryLock(timeout) 示例:");
        Thread t5 = new Thread(() -> reentrantDemo.tryLockWithTimeout(), "Thread-5");
        Thread t6 = new Thread(() -> reentrantDemo.tryLockWithTimeout(), "Thread-6");
        t5.start();
        t6.start();
        t5.join();
        t6.join();

        // 3. lockInterruptibly() 示例:先让一个线程持锁,另一个线程在 lockInterruptibly() 上阻塞,再中断阻塞线程
        System.out.println("\n3. lockInterruptibly() 示例(在等待锁时被中断):");
        Thread holder = new Thread(() -> reentrantDemo.holdLock(5000), "Holder");
        Thread interruptible = new Thread(() -> {
            try {
                reentrantDemo.lockInterruptiblyExample();
                System.out.println("Interruptible-Thread 正常结束");
            } catch (InterruptedException e) {
                System.out.println("Interruptible-Thread 在等待锁时被中断,抛出 InterruptedException");
                Thread.currentThread().interrupt();
            }
        }, "Interruptible-Thread");

        holder.start();
        Thread.sleep(100); // 确保 Holder 先拿到锁
        interruptible.start();
        Thread.sleep(800); // 此时 Interruptible 正在 lockInterruptibly() 上阻塞
        interruptible.interrupt(); // 中断正在等待锁的线程
        interruptible.join();
        holder.join();

        System.out.println("\n========== ReentrantLock 示例结束 ==========");
    }
}

代码运行结果:

text 复制代码
========== ReentrantLock 示例开始 ==========

1. 基本 lock() 示例:
Thread-1 [basicLock] 计数器: 1
Thread-2 [basicLock] 计数器: 2

2. tryLock(timeout) 示例:
Thread-5 [tryLockTimeout] 在500ms内获取成功
Thread-6 [tryLockTimeout] 在500ms内获取成功

3. lockInterruptibly() 示例(在等待锁时被中断):
Holder 持有锁 5000ms
Interruptible-Thread 尝试 lockInterruptibly(),若锁被占用将阻塞等待...
Interruptible-Thread 在等待锁时被中断,抛出 InterruptedException
Holder 释放锁

========== ReentrantLock 示例结束 ==========

ReentrantLock 使用示例

java 复制代码
package concurrent;

import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * ReentrantReadWriteLock 使用示例:
 * - 读锁(readLock):共享,多线程可同时持有,与写锁互斥
 * - 写锁(writeLock):独占,同一时刻仅一个线程可持有,与读锁、写锁均互斥
 */
public class ReentrantReadWriteLockDemo {

    private final ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private final ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
    private final ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();
    private String data = "initial";

    // 1. 读锁:多个线程可同时读
    public void readWithReadLock() {
        System.out.println(Thread.currentThread().getName() + " 尝试获取读锁");
        readLock.lock();  // 若写锁被占用,会在此阻塞
        try {
            System.out.println(Thread.currentThread().getName() + " 获取到读锁(写锁已释放后才会执行到这里)");
            System.out.println(Thread.currentThread().getName() + " [读锁] 读取: " + data);
            Thread.sleep(200);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            readLock.unlock();
        }
    }

    // 2. 写锁:独占,同一时刻只有一个线程可写
    public void writeWithWriteLock(String newData) {
        writeLock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " [写锁] 写入: " + newData);
            data = newData;
            Thread.sleep(300);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            writeLock.unlock();
        }
    }

    // 3. 持写锁一段时间,用于演示读/写互斥
    public void holdWriteLock(long millis) {
        writeLock.lock();
        try {
            System.out.println(Thread.currentThread().getName() + " 持有写锁 " + millis + "ms(此时读锁会阻塞)");
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 先打印再 unlock,保证控制台顺序能体现:先释放写锁,后读者才拿到读锁
            System.out.println(Thread.currentThread().getName() + " 释放写锁");
            writeLock.unlock();
        }
    }

    public static void main(String[] args) throws InterruptedException {
        ReentrantReadWriteLockDemo demo = new ReentrantReadWriteLockDemo();

        System.out.println("========== 1. 读锁共享:多个线程同时读 ==========");
        Thread r1 = new Thread(() -> demo.readWithReadLock(), "Reader-1");
        Thread r2 = new Thread(() -> demo.readWithReadLock(), "Reader-2");
        Thread r3 = new Thread(() -> demo.readWithReadLock(), "Reader-3");
        r1.start();
        r2.start();
        r3.start();
        r1.join();
        r2.join();
        r3.join();

        System.out.println("\n========== 2. 写锁独占:同一时刻只有一个写 ==========");
        Thread w1 = new Thread(() -> demo.writeWithWriteLock("A"), "Writer-1");
        Thread w2 = new Thread(() -> demo.writeWithWriteLock("B"), "Writer-2");
        w1.start();
        w2.start();
        w1.join();
        w2.join();

        System.out.println("\n========== 3. 读与写互斥:写锁持有时,读锁阻塞 ==========");
        Thread holder = new Thread(() -> demo.holdWriteLock(2000), "Writer-Holder");
        Thread reader = new Thread(() -> demo.readWithReadLock(), "Reader-Blocked");
        holder.start();
        Thread.sleep(100);
        reader.start();
        holder.join();
        reader.join();

        System.out.println("\n========== ReentrantReadWriteLock 示例结束 ==========");
    }
}

代码运行结果:

text 复制代码
========== 1. 读锁共享:多个线程同时读 ==========
Reader-1 尝试获取读锁
Reader-2 尝试获取读锁
Reader-3 尝试获取读锁
Reader-1 获取到读锁(写锁已释放后才会执行到这里)
Reader-2 获取到读锁(写锁已释放后才会执行到这里)
Reader-3 获取到读锁(写锁已释放后才会执行到这里)
Reader-1 [读锁] 读取: initial
Reader-3 [读锁] 读取: initial
Reader-2 [读锁] 读取: initial

========== 2. 写锁独占:同一时刻只有一个写 ==========
Writer-1 [写锁] 写入: A
Writer-2 [写锁] 写入: B

========== 3. 读与写互斥:写锁持有时,读锁阻塞 ==========
Writer-Holder 持有写锁 2000ms(此时读锁会阻塞)
Reader-Blocked 尝试获取读锁
Writer-Holder 释放写锁
Reader-Blocked 获取到读锁(写锁已释放后才会执行到这里)
Reader-Blocked [读锁] 读取: B

========== ReentrantReadWriteLock 示例结束 ==========

Lock 原理

Java lock机制使用AQS来管理锁的状态,进而管理同步锁的获取和释放。

使用AQS管理锁状态

AQS (AbstractQueuedSynchronizer) 是一个抽象接口,核心代码如下:

java 复制代码
// AQS 简化实现原理
public abstract class AbstractQueuedSynchronizer {
    
    // 核心字段1: 同步状态(32位int)
    private volatile int state;
    
    // 核心字段2: CLH队列(双向链表)
    private transient volatile Node head;  // 队列头
    private transient volatile Node tail;  // 队列尾
    
    // 队列节点
    static final class Node {
        volatile Node prev;      // 前驱节点
        volatile Node next;      // 后继节点
        volatile Thread thread;  // 等待的线程
        volatile int waitStatus; // 等待状态
        Node nextWaiter;        // 条件队列使用
    }
    
    // 核心方法:CAS操作
    protected final boolean compareAndSetState(int expect, int update) {
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }
}

ReentrantLock 使用 AQS 的 state 字段表示锁状态,类内部存在一个Sync内部类:

java 复制代码
// ReentrantLock 使用 AQS 的 state 字段表示锁状态
public class ReentrantLock {
    abstract static class Sync extends AbstractQueuedSynchronizer {
        // state 含义:
        // 0: 无锁状态
        // 1: 有线程持有锁(非重入)
        // N: 同一个线程重入了 N-1 次
    }
}

基于lock获取同步锁时,会经历以下流程:

graph TD A[线程尝试获取锁] --> B{是否持有锁?} B -->|是| C[重入计数+1] B -->|否| D{state是否为0?} D -->|是| E{公平锁?} E -->|是| F{有前驱节点?} F -->|无| G[CAS获取锁] F -->|有| H[入队等待] E -->|否| I[直接CAS尝试] I -->|成功| J[获取成功] I -->|失败| H D -->|否| H G --> K[获取成功] H --> L[进入CLH队列] L --> M[自旋或挂起] M --> N[被唤醒后尝试]

这里内部类Sync实现主要有公平锁和非公平锁两种实现,本文不展开深入,可看下篇文章。另外,这里涉及到的CLH 队列是一种自旋锁的等待队列实现,全称为 Craig, Landin, and Hagersten queue,是 AQS(AbstractQueuedSynchronizer)中实现线程排队等待的核心数据结构。

读写锁获取的实现

读写锁这里用到了state字段做了些状态设计:

java 复制代码
static class Sync extends AbstractQueuedSynchronizer {
    // 使用 state 的高16位表示读锁数量,低16位表示写锁重入次数
    // state = (读锁数量 << 16) | 写锁重入次数
    
    static final int SHARED_SHIFT   = 16;
    static final int SHARED_UNIT    = (1 << SHARED_SHIFT);  // 读锁单位: 65536
    static final int MAX_COUNT      = (1 << SHARED_SHIFT) - 1;  // 最大计数: 65535
    static final int EXCLUSIVE_MASK = (1 << SHARED_SHIFT) - 1;  // 写锁掩码: 0xFFFF
    
    // 获取读锁数量
    static int sharedCount(int c)    { return c >>> SHARED_SHIFT; }
    
    // 获取写锁重入次数
    static int exclusiveCount(int c) { return c & EXCLUSIVE_MASK; }
}

写锁获取的核心方法如下:

java 复制代码
// WriteLock 的 tryAcquire 方法
protected final boolean tryAcquire(int acquires) {
    Thread current = Thread.currentThread();
    int c = getState();
    int w = exclusiveCount(c);  // 获取写锁数量
    
    if (c != 0) {  // 有锁被持有
        // 情况1: 有读锁 (w == 0 但 c != 0)
        // 情况2: 有写锁但不是当前线程持有 (w != 0 && 持有者 != current)
        if (w == 0 || current != getExclusiveOwnerThread())
            return false;  // 获取失败
        
        // 情况3: 当前线程持有写锁(重入)
        if (w + exclusiveCount(acquires) > MAX_COUNT)
            throw new Error("Maximum lock count exceeded");
        setState(c + acquires);
        return true;
    }
    
    // c == 0 无锁状态
    if (writerShouldBlock() ||  // 公平性检查
        !compareAndSetState(c, c + acquires))
        return false;
    
    setExclusiveOwnerThread(current);
    return true;
}

读锁获取核心方法如下:

java 复制代码
// ReadLock 的 tryAcquireShared 方法
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)) {
        
        // 第一个读锁
        if (r == 0) {
            firstReader = current;
            firstReaderHoldCount = 1;
        }
        // 当前线程是第一个读锁持有者
        else if (firstReader == current) {
            firstReaderHoldCount++;
        }
        // 其他线程持有读锁
        else {
            HoldCounter rh = cachedHoldCounter;
            if (rh == null || rh.tid != current.getId())
                cachedHoldCounter = rh = readHolds.get();
            else if (rh.count == 0)
                readHolds.set(rh);
            rh.count++;
        }
        return 1;  // 获取成功
    }
    
    // CAS失败或应该阻塞,进入完整获取流程
    return fullTryAcquireShared(current);
}
相关推荐
止语Lab3 小时前
好的 DX 不等于少写代码——三种语言的摩擦力设计课
后端
吃饱了得干活3 小时前
别再手动解析 LLM 输出了!LangChain 四种结构化输出方案对比
后端·python·langchain
程序员天天困3 小时前
Arthas trace 命令怎么用?一行定位最慢那行代码
jvm·后端
Huiturn3 小时前
GPT 5.6 连续编码 10 小时,纯 Python 啃下 Word 二进制格式——doc2docx 实现拆解
后端
用户298698530143 小时前
Python 实现 Excel 与 Markdown 互转的实用指南
后端·python·excel
用户77283104908403 小时前
krono-job:零侵入、单二进制交付的分布式任务调度平台(开源)
后端
Conan在掘金3 小时前
鸿蒙报错速查:Function lacks ending return statement,返回路径漏 return 就炸,根因 + 真解法
后端
人间凡尔赛4 小时前
AI-Native 云原生架构:2026 年从容器编排到智能体编排的范式革命
后端·云原生·架构
IT_陈寒4 小时前
Vue的响应式让我加班到凌晨3点,原来问题出在这
前端·人工智能·后端
卷无止境4 小时前
提升 Python 代码健壮性的方法大盘点
后端·python