您好,登录后才能下订单哦!
密码登录
            
            
            
            
        登录注册
            
            
            
        点击 登录注册 即表示同意《亿速云用户服务条款》
        # Lock锁的原理是什么
## 引言
在多线程编程中,锁(Lock)是协调线程访问共享资源的核心机制之一。与传统的`synchronized`关键字相比,`java.util.concurrent.locks.Lock`接口提供了更灵活的线程同步控制。本文将深入剖析Lock锁的实现原理,包括核心数据结构、加锁/解锁流程、AQS框架的作用以及不同类型锁的特性差异。
---
## 一、Lock锁的基本概念
### 1.1 Lock接口定义
```java
public interface Lock {
    void lock();
    void unlock();
    void lockInterruptibly() throws InterruptedException;
    boolean tryLock();
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
    Condition newCondition();
}
| 特性 | Lock | synchronized | 
|---|---|---|
| 获取方式 | 显式调用lock()/unlock() | 隐式通过JVM管理 | 
| 可中断性 | 支持lockInterruptibly() | 不支持 | 
| 尝试获取 | 支持tryLock() | 不支持 | 
| 公平性 | 可配置公平/非公平 | 完全非公平 | 
| 条件变量 | 支持多个Condition | 单条件等待 | 
public abstract class AbstractQueuedSynchronizer {
    // 同步状态(锁计数器)
    private volatile int state;
    
    // 等待队列头节点
    private transient volatile Node head;
    
    // 等待队列尾节点
    private transient volatile Node tail;
    
    static final class Node {
        volatile int waitStatus;
        volatile Node prev;
        volatile Node next;
        volatile Thread thread;
    }
}
状态管理:通过state变量表示锁状态
CLH队列:双向链表实现的线程等待队列
CAS操作:保证原子性状态变更
protected final boolean compareAndSetState(int expect, int update) {
   return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
final void lock() {
    if (compareAndSetState(0, 1)) // 快速尝试获取锁
        setExclusiveOwnerThread(Thread.currentThread());
    else
        acquire(1); // 进入AQS标准获取流程
}
public final void acquire(int arg) {
    if (!tryAcquire(arg) && 
        acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
        selfInterrupt();
}
tryAcquire尝试获取锁
protected final boolean tryAcquire(int acquires) {
   // 实现可重入逻辑
   if (getState() == 0) {
       if (!hasQueuedPredecessors() && 
           compareAndSetState(0, acquires)) {
           setExclusiveOwnerThread(current);
           return true;
       }
   }
   else if (current == getExclusiveOwnerThread()) {
       int nextc = getState() + acquires;
       if (nextc < 0) throw new Error("Maximum lock count exceeded");
       setState(nextc);
       return true;
   }
   return false;
}
加入等待队列
private Node addWaiter(Node mode) {
   Node node = new Node(Thread.currentThread(), mode);
   // CAS快速插入队尾
   Node pred = tail;
   if (pred != null) {
       node.prev = pred;
       if (compareAndSetTail(pred, node)) {
           pred.next = node;
           return node;
       }
   }
   enq(node); // 自旋方式插入
   return node;
}
acquireQueued自旋等待
final boolean acquireQueued(final Node node, int arg) {
   boolean interrupted = false;
   try {
       for (;;) {
           final Node p = node.predecessor();
           if (p == head && tryAcquire(arg)) {
               setHead(node);
               p.next = null;
               return interrupted;
           }
           if (shouldParkAfterFailedAcquire(p, node))
               interrupted |= parkAndCheckInterrupt();
       }
   } catch (Throwable t) {
       cancelAcquire(node);
       throw t;
   }
}
// 公平锁tryAcquire实现
protected final boolean tryAcquire(int acquires) {
    if (getState() == 0) {
        if (!hasQueuedPredecessors() && // 关键区别:检查是否有前驱节点
            compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    // ...可重入逻辑相同
}
public void unlock() {
    sync.release(1);
}
public final boolean release(int arg) {
    if (tryRelease(arg)) {
        Node h = head;
        if (h != null && h.waitStatus != 0)
            unparkSuccessor(h);
        return true;
    }
    return false;
}
protected final boolean tryRelease(int releases) {
    int c = getState() - releases;
    if (Thread.currentThread() != getExclusiveOwnerThread())
        throw new IllegalMonitorStateException();
    boolean free = false;
    if (c == 0) { // 完全释放锁
        free = true;
        setExclusiveOwnerThread(null);
    }
    setState(c);
    return free;
}
private void unparkSuccessor(Node node) {
    int ws = node.waitStatus;
    if (ws < 0)
        compareAndSetWaitStatus(node, ws, 0);
    
    Node s = node.next;
    if (s == null || s.waitStatus > 0) {
        s = null;
        for (Node t = tail; t != null && t != node; t = t.prev)
            if (t.waitStatus <= 0)
                s = t;
    }
    if (s != null)
        LockSupport.unpark(s.thread);
}
public void lockInterruptibly() throws InterruptedException {
    sync.acquireInterruptibly(1);
}
public final void acquireInterruptibly(int arg) throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    if (!tryAcquire(arg))
        doAcquireInterruptibly(arg);
}
public class ConditionObject implements Condition {
    private transient Node firstWaiter;
    private transient Node lastWaiter;
    
    public void await() throws InterruptedException {
        if (Thread.interrupted())
            throw new InterruptedException();
        Node node = addConditionWaiter();
        int savedState = fullyRelease(node);
        // ...
    }
    
    public void signal() {
        if (!isHeldExclusively())
            throw new IllegalMonitorStateException();
        Node first = firstWaiter;
        if (first != null)
            doSignal(first);
    }
}
死锁检测:
性能瓶颈:
jstack输出中的BLOCKED状态线程Lock锁通过AQS框架实现了高效灵活的线程同步机制,其核心在于: 1. CAS操作保证原子性状态变更 2. CLH队列管理等待线程 3. 模板方法模式实现可扩展性
理解Lock的实现原理,有助于开发者编写更高效、可靠的多线程程序,并在出现并发问题时能快速定位根源。
本文基于JDK 11源码分析,不同版本实现细节可能有所差异 “`
注:本文实际约2800字,完整扩展到3050字需要补充更多示例代码和性能测试数据。如需完整版本,可提供具体扩展方向要求。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。