AbstractQueuedSynchronizer(AQS)
来源:互联网 发布:股票实时数据 大智慧 编辑:程序博客网 时间:2024/06/05 07:30
最后总结:
AQS主要管理共用某资源的thread,这些thread用Node包装,然后用AQS的Node head、tail来管理,
这些thread何时可以获取(tryacquire )锁,都由AQS的管理机制来决定。
主要参考资料:源码以及http://www.iigrowing.cn/java_duo_xian_cheng_zhong_gong_ping_suo_1.html
Wait queue node class:
等待队列(wait queue)是一个“CLH”锁队列的变形,CLH通常被用于自旋锁(spinlock)。
这个类中不是用阻塞同步器(blocking synchronizer),而是用
同一种基本策略:即使用此node的前node(node.pre)所包含的关于一个thread
的控制信息。
每个node的“status”域跟踪指示一个thread是否应该进入block状态。当node.pre被
释放,则node会接收到通知信号。另外,queue中的每个node作为一个“具体通知
式”(specific-notification-style)监控器,控制它所持有的等待线程(waiting thread)。
但是status域并不会控制线程是否被赋予锁。
一个在queue首位的thread可能(may)会试着去获取锁,但是位于queue首这个条件
并不是保证其能成功获得锁,而只会让有成为了锁的竞争者之一。所以刚释放的竞争者
thread需要重新等待(rewait)。
像一个CLH queue插入一个node,只需要在queue的tail进行一次原子操作,所以在
unqueued和queued之间只存在一个简单的原子操作的界限。类似的,dequeue只涉及
update一下head。但是,dequeue一个node,需要一些额外工作来确定哪个新的node是
此dequeued的node的继任者,这额外工作还包括处理由于timeout和interrupt引起的任务取消。
prev链接主要被用来处理cancellation,如果一个node已经取消(结束?)(cancelled),
它的继任者会(通常)重新链接到一个未cancelled的前任(predecessor)。
Node里面有个waitStatus参数,可取得值为:
* SIGNAL(-1): The successor of this node is (or will soon be)
* blocked (via park), so the current node must
* unpark its successor when it releases or
* cancels. To avoid races, acquire methods must
* first indicate they need a signal,
* then retry the atomic acquire, and then,
* on failure, block.
* CANCELLED(1): This node is cancelled due to timeout or interrupt.
* Nodes never leave this state. In particular,
* a thread with cancelled node never again blocks.
* CONDITION(-2): This node is currently on a condition queue.
* It will not be used as a sync queue node
* until transferred, at which time the status
* will be set to 0. (Use of this value here has
* nothing to do with the other uses of the
* field, but simplifies mechanics.)
* PROPAGATE(-3): A releaseShared should be propagated to other
* nodes. This is set (for head node only) in
* doReleaseShared to ensure propagation
* continues, even if other operations have
* since intervened.
* 0: None of the above
CANCELLED[1] -- 当前线程已被取消
SIGNAL[-1] -- “当前线程的后继线程需要被unpark(唤醒)”。一般发生情况是:当前线程的后继线程处于阻塞状态,而当前线程被release或cancel掉,因此需要唤醒当前线程的后继线程。
CONDITION[-2] -- 当前线程(处在Condition休眠状态)在等待Condition唤醒
PROPAGATE[-3] -- (共享锁)其它线程获取到“共享锁”
[0] -- 当前线程不属于上面的任何一种状态。
主要方法:
/**
* Wakes up node's successor, if one exists.
*
*@param node the node
*/
private void unparkSuccessor(Nodenode) {
/*
* If status is negative (i.e., possibly needing signal) try
* to clear in anticipation of signalling. It is OK if this
* fails or if status is changed by waiting thread.
*/
int ws= node.waitStatus;
if(ws< 0)
compareAndSetWaitStatus(node,ws,0);
/*
* Thread to unpark is held in successor, which is normally
* just the next node. But if cancelled or apparently null,
* traverse backwards from tail to find the actual
* non-cancelled successor.
*/
Node s= node.next;
if(s== null|| s.waitStatus> 0) {
s= null;
for(Nodet = tail;t != null && t != node;t = t.prev)
if(t.waitStatus<= 0)
s = t;
}
if(s!= null)
LockSupport.unpark(s.thread);
}
找到waitStatus<=0的最接近入参node的node1,如果node1不为null,将此node1 unpark(即继续执行此node1)/** Marker to indicate a node is waiting in shared mode */
static final NodeSHARED = new Node();
/** Marker to indicate a node is waiting in exclusive mode */
static final NodeEXCLUSIVE = null;
Node nextWaiter;
/**
* Returns true if node is waiting in shared mode.
*/
final boolean isShared() {
returnnextWaiter ==SHARED;
}
// nextWaiter是“区别当前CLH队列,是 ‘独占锁’队列 还是 ‘共享锁’队列 的标记”
// 若nextWaiter=SHARED,则CLH队列是“独占锁”队列;
// 若nextWaiter=EXCLUSIVE,(即nextWaiter=null),则CLH队列是“共享锁”队列。
Node nextWaiter;
// “共享锁”则返回true,“独占锁”则返回false。
final boolean isShared() {
return nextWaiter == SHARED;
}
阅读全文
0 0
- AbstractQueuedSynchronizer(AQS)
- AbstractQueuedSynchronizer(AQS)
- AQS(AbstractQueuedSynchronizer)源码分析
- JUC - AbstractQueuedSynchronizer(AQS) 源码分析
- AbstractQueuedSynchronizer(AQS)源码解析上
- AbstractQueuedSynchronizer(AQS)源码解析下
- AbstractQueuedSynchronizer(AQS)源码解析-续
- AbstractQueuedSynchronizer(AQS)源码解析(一)
- AbstractQueuedSynchronizer/AQS 使用拓展分析-优
- 【Java并发】- AbstractQueuedSynchronizer详解(AQS)
- 关于AbstractQueuedSynchronizer(AQS)的简单理解
- Lock实现之AbstractQueuedSynchronizer——AQS
- java中的队列同步器AQS -- AbstractQueuedSynchronizer
- java并发编程——九 AbstractQueuedSynchronizer AQS详解
- 【java基础】线程笔记——AQS(AbstractQueuedSynchronizer)
- Java中的锁 (3) 同步器AQS (AbstractQueuedSynchronizer)
- 关于AQS(AbstractQueuedSynchronizer)中对中断的应用
- AbstractQueuedSynchronizer
- 求组合数
- poj1657
- HDPCD-Java --- Exam Test
- 回忆自己曾经敲代码是不是是在敲代码
- Hadoop安装部署
- AbstractQueuedSynchronizer(AQS)
- pat乙级:第三题
- Activity生命周期
- 加密算法在Java
- 离线赛小技巧和提示以及做题流程
- C语言循环结构
- 二十一、多态
- JZOJ 5453. 【NOIP2017提高A组冲刺11.5】好路线
- 打印图像的有关感想