ReentrantLock源码简单查看

非公平锁LOCK方法

final void lock() {
    if (compareAndSetState(0, 1))  // 尝试通过CAS的方式将state设1
        setExclusiveOwnerThread(Thread.currentThread());
    else
        acquire(1); // 获取所资源
}

AQS(AbstractQueuedSynchronizer)
内部维护了个由Node类组成的双向链表结构.
并且由state标识当前锁资源是否被占有,大于0就代表有线程占有了资源

	// AQS链表头节点
	private transient volatile Node head;
	// 尾部节点
    private transient volatile Node tail;

    // 每次有线程获取锁,state加1,大于0就代表有线程占有了资源
    private volatile int state;
	// 当前占有所资源的线程
    private transient Thread exclusiveOwnerThread;

 	public final void acquire(int arg) {
        if (!tryAcquire(arg) && // 如果没获取到锁,
                acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) {
            selfInterrupt();
        }
    }

非公平锁尝试获取所资源

final boolean nonfairTryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
        // 通过CAS的方式将state从0修改为1,返回true代表修改成功,
        if (compareAndSetState(0, acquires)) {
            setExclusiveOwnerThread(current);
            return true;
        }
    }
    // 当前占有所资源的线程是否是当前
    else if (current == getExclusiveOwnerThread()) {
        int nextc = c + acquires;
        if (nextc < 0) // overflow
            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);
    // Try the fast path of enq; backup to full enq on failure
    Node pred = tail;
    if (pred != null) {
        node.prev = pred;  // 插入到双向链表的尾部
        if (compareAndSetTail(pred, node)) {  // 基于cas将刚创建的节点设为尾部节点
            pred.next = node;
            return node;
        }
    }
    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()) // 基于Unsafe类的park方法,将线程挂起
	             interrupted = true;
	     }
	 } finally {
	     if (failed)
	         cancelAcquire(node);
	 }
}

Node节点

public class Node {

    // 排他锁标识
    static final Node EXCLUSIVE = null;

    // 失效
    static final int CANCELLED = 1;

    // 有这标识,代表后继节点需要被唤醒
    static final int SIGNAL    = -1;
    static final int CONDITION = -2;
    static final int PROPAGATE = -3;

    // Node对象存储标识的地方
    volatile int waitStatus;

    // 上一个节点,前驱节点
    volatile Node prev;

    // 下一个节点,后继节点
    volatile Node next;

    // 当前节点绑定的线程
    volatile Thread thread;

    private Node nextWaiter;

    final Node predecessor() throws NullPointerException {
        Node p = prev;
        if (p == null)
            throw new NullPointerException();
        else
            return p;
    }
}
  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值