在分析ReentrantReadWriteLock 时知道多个线程在争论一个state,那么当时数据放在那里呢。都是放在syns里,这个类继承了AbstractQueuedSynchronizer,而里面的node(链表)就是存储数据的。
所以其实所有的lock 是离不开的队列的。今天的condition 也是离不开队列,也离不开lock,所以其实现类就放在
AbstractQueuedSynchronizer。名为:ConditionObject
Condition 通过 lock的newCondition() 方法生存,就像wait和notify 离不开同步块或者同步方法一样。
Condition newCondition();
每一个condition存储了头和尾
private transient Node firstWaiter; /** Last node of condition queue. */ private transient Node lastWaiter;
await操作:
添加一个await操作,就是放里面添加一个节点:(如果看不懂,可以先看看数据结构,学习java 也是必须懂数据结构和算法的,如果不懂底层,能力很难提高,发个感慨------最近面试了很多人,其中很多人都工作很多年,但是一问三不知,工作都停留表面,可能是工作内容的原因(比如:工作轻松,或者完成一个demo,或者完成一些简单后台工作),同样的项目,努力的人会去努力了解底层,了解全部架构,知其然,该知其所以然,才能提高哦,可是什么都不开,天天就是MVC,写写restful,完成个页面,完成个后台,拿到的都是别人搭好的架构和接口要求,这样你做再久也就这样了。。。。。。话多余了。。。。。)
private Node addConditionWaiter() {
Node t = lastWaiter;
// If lastWaiter is cancelled, clean out.
if (t != null && t.waitStatus != Node.CONDITION) {
unlinkCancelledWaiters();
t = lastWaiter;
}
//注意这个,将节点变成了条件等待。
Node node = new Node(Thread.currentThread(), Node.CONDITION);
if (t == null)
firstWaiter = node;
else
t.nextWaiter = node;
lastWaiter = node;
return node;
}
signal操作:
重头开始遍历,依次做
transferForSignal
private void doSignal(Node first) {
do {
if ( (firstWaiter = first.nextWaiter) == null)
lastWaiter = null;
first.nextWaiter = null;
} while (!transferForSignal(first) &&
(first = firstWaiter) != null);
}
会去改变
waitStatus
的值,看来condition也是争一个变量了
final boolean transferForSignal(Node node) {
/*
* If cannot change waitStatus, the node has been cancelled.
*/
if (!compareAndSetWaitStatus(node, Node.CONDITION, 0))
return false;
Node p = enq(node);
int ws = p.waitStatus;
if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL))
LockSupport.unpark(node.thread);
return true;
}
对象的等待和running:
这里涉及到变量的变化,还有一个就是怎么停车的。是通过
LockSupport,可以参考我的(
jdk 源码分析(10)java unsafe 分析)
等待:
public final void await() throws InterruptedException {
if (Thread.interrupted())
throw new InterruptedException();
//添加节点,并且节点是waitStatus 是condition(-2)
Node node = addConditionWaiter();
int savedState = fullyRelease(node);
int interruptMode = 0;
while (!isOnSyncQueue(node)) {
//停车
LockSupport.park(this);
if ((interruptMode = checkInterruptWhileWaiting(node)) != 0)
break;
}
if (acquireQueued(node, savedState) && interruptMode != THROW_IE)
interruptMode = REINTERRUPT;
if (node.nextWaiter != null) // clean up if cancelled
unlinkCancelledWaiters();
if (interruptMode != 0)
reportInterruptAfterWait(interruptMode);
}
final boolean transferForSignal(Node node){
/*
*If cannot change waitStatus, the node has been cancelled.
*/
if(!compareAndSetWaitStatus(node,Node.CONDITION,0))
return false;
Node p = enq(node);
int ws= p.waitStatus;
//数据被signal 。unpark
if(ws>0||!compareAndSetWaitStatus(p, ws,Node.SIGNAL))
LockSupport.unpark(node.thread);
return true;
}
到此结束:
condition 用一个链表(Node)队列(FIFO)缓存wait,通过争论waitstute来改变状态,通过park和unpark来释放和等待