java并发编程--AbstractQueuedSynchronizer公平锁和非公平锁分析(三)
2015-08-13 11:31
796 查看
juc包中,aqs实现的公平锁和非公平锁的最主要的区别是:非公平锁中,那些尝试获取锁且尚未进入等待队列的线程会和等待队列head结点的线程发生竞争。公平锁中,在获取锁时,增加了isFirst(current)判断,当且仅当,等待队列为空或当前线程是等待队列的头结点时,才可尝试获取锁。
1.1 NonfairSync.lock()
Java代码
final void lock() {
if (compareAndSetState(0, 1))//没有进入等待队列,也可以获取锁
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
2.1 FairSync.lock()
Java代码
final void lock() {
acquire(1);
}
2.2 FairSync.tryAcquire()
Java代码
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (isFirst(current) &&//只有等待队列为空或当前线程是队列头结点才可以获取锁
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
关于当前线程是否是队列头结点的判断,详见下面两个函数:
2.3 AbstractQueuedSynchronizer.isFirst()
Java代码
/**
* Return {@code true} if the queue is empty or if the given thread
* is at the head of the queue. This is reliable only if
* <tt>current</tt> is actually Thread.currentThread() of caller.
*/
final boolean isFirst(Thread current) {
Node h, s;
return ((h = head) == null ||
((s = h.next) != null && s.thread == current) ||
fullIsFirst(current));
}
2.4 AbstractQueuedSynchronizer.fullIsFirst()
Java代码
final boolean fullIsFirst(Thread current) {
// same idea as fullGetFirstQueuedThread
Node h, s;
Thread firstThread = null;
if (((h = head) != null && (s = h.next) != null &&
s.prev == head && (firstThread = s.thread) != null))
return firstThread == current;
Node t = tail;
while (t != null && t != head) {
Thread tt = t.thread;
if (tt != null)
firstThread = tt;
t = t.prev;
}
return firstThread == current || firstThread == null;
}
总结:
线程为首结点成立的情况:
1.等待队列为空。
2.等待队列head的next结点的thread为当前线程(head.next.thread = currentThread),即线程为等待队列除哑结点外的第一个结点。
3.等待队列head结点到某个结点(暂命名为结点s),之间的所有结点的thread变量为null,且结点s的thread为当前线程。
原文http://suo.iteye.com/blog/1330485
1.1 NonfairSync.lock()
Java代码
final void lock() {
if (compareAndSetState(0, 1))//没有进入等待队列,也可以获取锁
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
2.1 FairSync.lock()
Java代码
final void lock() {
acquire(1);
}
2.2 FairSync.tryAcquire()
Java代码
/**
* Fair version of tryAcquire. Don't grant access unless
* recursive call or no waiters or is first.
*/
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (isFirst(current) &&//只有等待队列为空或当前线程是队列头结点才可以获取锁
compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
关于当前线程是否是队列头结点的判断,详见下面两个函数:
2.3 AbstractQueuedSynchronizer.isFirst()
Java代码
/**
* Return {@code true} if the queue is empty or if the given thread
* is at the head of the queue. This is reliable only if
* <tt>current</tt> is actually Thread.currentThread() of caller.
*/
final boolean isFirst(Thread current) {
Node h, s;
return ((h = head) == null ||
((s = h.next) != null && s.thread == current) ||
fullIsFirst(current));
}
2.4 AbstractQueuedSynchronizer.fullIsFirst()
Java代码
final boolean fullIsFirst(Thread current) {
// same idea as fullGetFirstQueuedThread
Node h, s;
Thread firstThread = null;
if (((h = head) != null && (s = h.next) != null &&
s.prev == head && (firstThread = s.thread) != null))
return firstThread == current;
Node t = tail;
while (t != null && t != head) {
Thread tt = t.thread;
if (tt != null)
firstThread = tt;
t = t.prev;
}
return firstThread == current || firstThread == null;
}
总结:
线程为首结点成立的情况:
1.等待队列为空。
2.等待队列head的next结点的thread为当前线程(head.next.thread = currentThread),即线程为等待队列除哑结点外的第一个结点。
3.等待队列head结点到某个结点(暂命名为结点s),之间的所有结点的thread变量为null,且结点s的thread为当前线程。
原文http://suo.iteye.com/blog/1330485
相关文章推荐
- java并发编程--AbstractQueuedSynchronizer条件锁分析(四)
- java并发编程--AbstractQueuedSynchronizer的lock()和lockInterruptibly()方法分析(五)
- java并发编程--AbstractQueuedSynchronizer的tryLock()方法分析(六)
- 线程池--jetty中QueuedThreadPool分析(一)
- quick 3.3final 编译成功 运行出错的问题
- 关于研究UIautomator操作手机执行case
- OPEN(SAP) UI5 学习入门系列之二: 最佳实践练习(上)
- 使用Hibernate SQLQuery执行原生SQL
- PHP中include和require的区别详解
- 反射(Reflection)的SetValue遇上DBNULL转换为string
- android 开源组件合集-UI篇(2014-08-25更新)
- hdu 5147 Sequence II(前缀和,后缀和)
- The Unique MST (判断是否存在多个最小生成树)
- Flex与服务器交互之一(URLRequest +URLLoader应用)
- requestWindowFeature()的应用
- iOS-UItableView 多组表格
- 将UE添加到鼠标右键打开
- Hibernate使用Query进行查询
- HDU 1242 Rescue(广搜,优先队列)
- UITableView错误 ‘unable to dequeue a cell with identifier Cell'