Java多线程系列--“JUC锁”04之 公平锁(二)(一)

2014-11-24 03:05:43 · 作者: · 浏览: 3
1. Re:Java多线程系列--“JUC锁”03之 公平锁(一)
高级货
--Alvin
2. Re:Java Calendar,Date,DateFormat,TimeZone,Locale等时间相关内容的认知和使用(2) 自己封装的Calendar接口
你好,我也在用这个ChineseCalendar,发现农历set进入1月后应用就无反映了,所以上网找一下看看,发现了你已修改,可以说一下情况吗 。你修改的这个ChineseCalendar也还有问题,农历92年11月30时会变成93年,而28时还是92年,之后12月也会变成93年。
--沦落凡间
3. Re:Java多线程系列--“基础篇”05之 线程等待与唤醒
还不错,如果例子再清晰一点就好了,理解起来有点绕。
以后还多交流哈
--卡拉马佐夫少校
4. Re:Java 集合系列05之 LinkedList详细介绍( 源码解析)和使用示例
引用
首先会比较“location”和“双向链表长度的1/2”;若前者大,则从链表头开始往后查找,直到location位置;
应该是“location”小于“双向链表长度的1/2”才从头开始往后查找
--yunfeiyang0514
5. Re:Java多线程系列--“基础篇”11之 生产消费者问题
@szyuxueliang
yes
--如果天空不死
阅读排行榜
1. Android layout属性详细说明(2566)
2. Android 之窗口小部件详解--App Widget(2341)
3. Java 集合系列目录(Category)(2221)
4. Android 布局之GridLayout(1605)
5. Java 集合系列03之 ArrayList详细介绍(源码解析)和使用示例(1328)
Java多线程系列--“JUC锁”04之 公平锁(二)
概要
前面一章,我们学习了“公平锁”获取锁的详细流程;这里,我们再来看看“公平锁”释放锁的过程。内容包括:
参考代码
释放公平锁(基于JDK1.7.0_40)
“公平锁”的获取过程请参考“Java多线程系列--“JUC锁”03之 公平锁(一)”,锁的使用示例请参考“Java多线程系列--“JUC锁”02之 互斥锁ReentrantLock”。
注意:
(01) 这里是以“公平锁”来进行说明。
(02) 关于本章的术语,如“AQS”,“CAS函数”,“CLH队列”,“公平锁”,“非公平锁”,“独占锁”,“共享锁”等内容,请参考Java多线程系列--“JUC锁”03之 公平锁(一)的基本概念。
转载请注明出处:http://www.cnblogs.com/skywang12345/p/3496609. html
参考代码
下面给出Java1.7.0_40版本中,ReentrantLock和AQS的源码,仅供参考!
ReentranLock.java
View Code
AQS(AbstractQueuedSynchronizer.java)
View Code
释放公平锁(基于JDK1.7.0_40)
1. unlock()
unlock()在ReentrantLock.java中实现的,源码如下:
public void unlock() {
sync.release(1);
}
说明:
unlock()是解锁函数,它是通过AQS的release()函数来实现的。
在这里,“1”的含义和“获取锁的函数acquire(1)的含义”一样,它是设置“释放锁的状态”的参数。由于“公平锁”是可重入的,所以对于同一个线程,每释放锁一次,锁的状态-1。
关于AQS, ReentrantLock 和 sync的关系如下:
复制代码
public class ReentrantLock implements Lock, java.io.Serializable {
private final Sync sync;
abstract static class Sync extends AbstractQueuedSynchronizer {
...
}
...
}
复制代码
从中,我们发现:sync是ReentrantLock.java中的成员对象,而Sync是AQS的子类。
2. release()
release()在AQS中实现的,源码如下:
复制代码
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
复制代码
说明:
release()会先调用tryRelease()来尝试释放当前线程锁持有的锁。成功的话,则唤醒后继等待线程,并返回true。否则,直接返回false。
3. tryRelease()
tryRelease()在ReentrantLock.java的Sync类中实现,源码如下:
复制代码
protected final boolean tryRelease(int releases) {
// c是本次释放锁之后的状态
int c = getState() - releases;
// 如果“当前线程”不是“锁的持有者”,则抛出异常!
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
// 如果“锁”已经被当前线程彻底释放,则设置“锁”的持有者为null,即锁是可获取状态。
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
// 设置当前线程的锁的状态。
setState(c);
return free;
}
复制代码
说明:
tryRelease()的作用是尝试释放锁。
(01) 如果“当前线程”不是“锁的持有者”,则抛出异常。
(02) 如果“当前线程”在本次释放锁操作之后,对锁的拥有状态是0(即,当前线程彻底释放该“锁”),则设置“锁”的持有者为null,即锁是可获取状态。同时,更新当前线