AQS共享锁独占锁

AQS公共源码解析

部分源码

public abstract class AbstractQueuedSynchronizer 
extends AbstractOwnableSynchronizer
implements java.io.Serializable {

	private transient volatile Node head;//头结点
	private transient volatile Node tail;//尾结点
	private volatile int state;//同步状态	0:未持有 1:被占有
	
	static final class Node {
		static final Node SHARED = new Node();//共享
	    static final Node EXCLUSIVE = null;//独占
		
		volatile int waitStatus;//等待状态
		volatile Node prev;
		volatile Node next;
		volatile Thread thread;
		Node nextWaiter;//为共享模式使用的字段,链式唤醒
	}
	//加入队列
	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)) {
	            pred.next = node;
	            return node;
	        }
	    }
	    enq(node);	//队列为空时
	    return node;
	}

	//初始化队列
	private Node enq(final Node node) {
	    for (;;) {
	        Node t = tail;
	        if (t == null) { // Must initialize
	            if (compareAndSetHead(new Node()))//空节点作为head节点(哨兵节点)
	                tail = head;
	        } else {
	            node.prev = t;
	            if (compareAndSetTail(t, node)) {
	                t.next = node;
	                return t;
	            }
	        }
	    }
	}
}	

AQS中tryAcquire、tryAcquireShared、tryRelease、tryReleaseShared、isHeldExclusively几个方法方法体中均只定义了throw new UnsupportedOperationException(),没有定义具体实现,目的是让子类去订制实现,增加扩展性。

例如:
ReentrantLock中重写了tryAcquire、tryRelease,CountDownLatch重写了tryAcquireShared、tryReleaseShared

AQS独占锁(ReentrantLock)

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))//独占锁,即node. nextWaiter = Node.EXCLUSIVE
        selfInterrupt();
}
//ReentrantLock中tryAcquire具体实现
final boolean nonfairTryAcquire(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) // overflow
            throw new Error("Maximum lock count exceeded");
        setState(nextc);
        return true;
    }
    return false;
}
//AQS:排队获取(自旋阻塞)
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())//LockSupport.park(this);阻塞线程
                interrupted = true;
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}

AQS共享锁(CountDownLatch)

public void await() throws InterruptedException {
    sync.acquireSharedInterruptibly(1);
}

public final void acquireSharedInterruptibly(int arg)
        throws InterruptedException {
    if (Thread.interrupted())
        throw new InterruptedException();
    if (tryAcquireShared(arg) < 0)
        doAcquireSharedInterruptibly(arg);
}
//直接获取共享锁
protected int tryAcquireShared(int acquires) {
    return (getState() == 0) ? 1 : -1;
}
//尝试获取共享锁
private void doAcquireSharedInterruptibly(int arg)
throws InterruptedException {
//Node.SHARED:共享模式,即 node.nextWaiter = Node.SHARED;
    final Node node = addWaiter(Node.SHARED);
    boolean failed = true;
    try {
        for (;;) {
            final Node p = node.predecessor();
            if (p == head) {
                int r = tryAcquireShared(arg);
                if (r >= 0) {
                    setHeadAndPropagate(node, r);//设置头结点并传播(共享模式)
                    p.next = null; // help GC
                    failed = false;
                    return;
                }
            }
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())//LockSupport.park(this);阻塞线程
                throw new InterruptedException();
        }
    } finally {
        if (failed)
            cancelAcquire(node);
}

//设置头结点并传播(共享模式)
private void setHeadAndPropagate(Node node, int propagate) {
    Node h = head; // Record old head for check below
    setHead(node);
   
    if (propagate > 0 || h == null || h.waitStatus < 0 ||
        (h = head) == null || h.waitStatus < 0) {
        Node s = node.next;
        if (s == null || s.isShared())
            doReleaseShared();//唤醒其他
    }
}

总结

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值