// 当前持有独占锁的线程
private transient Thread exclusiveOwnerThread;

static final Node SHARED = new 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; // 释放共享资源时需要通知其他节点
// 等待状态
volatile int waitStatus;
// 结点前驱
volatile Node prev;
// 结点后继
volatile Node next;
// 结点的线程
volatile Thread thread;
// 下一个等待者
Node nextWaiter;
private transient volatile Node head;
private transient volatile Node tail;
注意:
-
head指针指向一个标杆结点(或称哨兵结点),标杆结点也是一个Node对象,但该Node对象不维护任何线程,只是起一个标杆的作用。
-
getState() -
setState() -
compareAndSetState()
-
比如ReentantLock独占锁,state初始化为0,第一个来的线程成功将state从0修改为1,那么第一个线程将持有锁,且该线程可重入,每重入一次state就加1;但重入多少次就要释放(state–)多少次,直到state为0表示第一个线程释放了锁。在第一个线程持有锁期间,由于是独占锁,其它线程只能等待; -
再比如CountDownLatch,一开始有n个子线程,state也初始化为n,这n个子线程是并行执行的,且主线程会调用await()方法等待;每有一个线程执行结束,就调用一次countDown()方法,state–;直到n个线程都执行完了,state减为0,会调用unpark()方法唤醒主线程使其从await()方法中返回;
-
Exclusive(独占,只有一个线程能执行,如ReentrantLock); -
Share(共享,多个线程可同时执行,如Semaphore/CountDownLatch);
-
isHeldExclusively():该线程是否正在独占资源,只有用到condition才需要去实现它; -
tryAcquire(int):独占方式,尝试获取资源; -
tryRelease(int):独占方式,试释放资源; -
tryAcquireShared(int):共享方式,尝试获取资源; -
tryReleaseShared(int):共享方式,尝试释放资源;
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
protected boolean tryRelease(int arg) {
throw new UnsupportedOperationException();
}
protected int tryAcquireShared(int arg) {
throw new UnsupportedOperationException();
}
protected boolean tryReleaseShared(int arg) {
throw new UnsupportedOperationException();
}
protected boolean isHeldExclusively() {
throw new UnsupportedOperationException();
}
-
tryAcquire+tryRelease -
tryAcquireShared+tryReleaseShared
原文始发于微信公众号(初心JAVA):并发第六弹 AQS抽象队列同步器
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之家整理,本文链接:https://www.bmabk.com/index.php/post/35540.html