java锁(1)之ReentrantLock
2016-01-24 11:00
405 查看
ReentrantLock
1. 特点:1) ReentrantLock提供了两种锁:公平锁和非公平锁。
2) ReentrantLock是可重入的:一个线程可以多次调用lock成功,但要求调用了多少次lock,就需要对应调用多少次unlock
3) ReentrantLock除了实现Lock接口外,还提供了一些辅助的方法,如:isLocked和getQueueLength等,这些方法对检测和监视可能很有用。
非公平锁
1. 获取一个非公平锁:2. 实现:
1) 获取锁资源:通过ReentLock的lock来申请锁。
使用的AQS实现类NofairSync(非公平同步)的lock方法。
在新线程获取锁是没有加任何限制,这里体现了非公平性,即新的和旧的一起竞争。
a) 通过CAS操作,比较并设置锁的状态,来改变锁的状态。即尝试去获取锁。0与当前所得状态比较,若相等需改(获取)成功。
b) 若成功,修改当前锁的owner为自己。
c) 若不成功,调用acquire()方法。在acquire中干了如下几件事
Ø 再次尝试获取锁,若成功则返回。
u 获取当前锁的状态
u 若空闲,则修改锁的状态、是指锁的owner为自己,返回True
u 若不空闲,则判断锁的持有者是否是自己
n 若是,锁状态+1,返回True
u 返回false
Ø 再次获取锁失败后,将本线程通过addWaiter()方法将自己加入等待队列中,返回在等待队列中表示本线程的结点。
Ø 使线程进入阻塞睡眠。
2) 释放锁资源:通过ReentLock的unlock来释放锁
使用AQS的release方法。
Ø release中线程使用tryRelease释放锁,释放锁成功后将进入唤醒等待线程;
Ø 如果队列不为空,并且head的waitStatus不为0,即存在后续节点的线程等待被唤醒,则调用unparkSuccessor唤醒后续节点的线程。
Ø 否则返回false
a) tryRelease(int arg):
Ø tryRelease中获取AQS的状态,并减去releases(释放锁),得到c;
Ø 如果执行的线程不是锁的owner,则抛出异常
Ø 若是,则判断c(表示剩余需要被释放的次数)
n 如果c为0,则表示锁已经被释放,将锁的owner设置为空,
n 设置AQS的state状态标志位为c;(此时c为当先还需unlock的次数,可能是0,也可能不是0)
n 返回锁是否都释放了。
b) 若tryRelease返回true表示锁锁了等同的unlock操作。即锁释放。
Ø 使用unparkSuccessor唤醒等待队列中对头的阻塞线程。
Ø 若后续中还存在可被唤醒的线程,则继续唤醒。
公平锁
1. 公平锁和非公平锁区别:1) 非公平锁是新到的线程和等待队列中的线程一起竞争锁;
2) 公平锁则始终保证等待最长的线程获取锁。
Ø 公平锁和非公平锁的区别就在于多了hasQueuedPredecessors判断
Ø hasQueuedPredecessors判断是否有等待线程。
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序
- 二叉查找树