Java8对读写锁的改进:StampedLock
来源:互联网 发布:ubuntu selinux 状态 编辑:程序博客网 时间:2024/05/19 12:16
该类是一个读写锁的改进,它的思想是读写锁中读不仅不阻塞读,同时也不应该阻塞写。
读不阻塞写的实现思路:
在读的时候如果发生了写,则应当重读而不是在读的时候直接阻塞写!
因为在读线程非常多而写线程比较少的情况下,写线程可能发生饥饿现象,也就是因为大量的读线程存在并且读线程都阻塞写线程,
因此写线程可能几乎很少被调度成功!当读执行的时候另一个线程执行了写,则读线程发现数据不一致则执行重读即可。所以读写都存在的情况下,
使用StampedLock就可以实现一种无障碍操作,即读写之间不会阻塞对方,但是写和写之间还是阻塞的!
程序举例:
public class Point {
//一个点的x,y坐标
private double x,y;
/**Stamped类似一个时间戳的作用,每次写的时候对其+1来改变被操作对象的Stamped值
* 这样其它线程读的时候发现目标对象的Stamped改变,则执行重读*/
private final StampedLock stampedLock = new StampedLock();
// an exclusively locked method
void move(doubledeltaX,doubledeltaY) {
/**stampedLock调用writeLock和unlockWrite时候都会导致stampedLock的stamp值的变化
* 即每次+1,直到加到最大值,然后从0重新开始 */
longstamp =stampedLock.writeLock(); //写锁
try {
x +=deltaX;
y +=deltaY;
} finally {
stampedLock.unlockWrite(stamp);//释放写锁
}
}
double distanceFromOrigin() { // A read-only method
/**tryOptimisticRead是一个乐观的读,使用这种锁的读不阻塞写
* 每次读的时候得到一个当前的stamp值(类似时间戳的作用)*/
longstamp =stampedLock.tryOptimisticRead();
//这里就是读操作,读取x和y,因为读取x时,y可能被写了新的值,所以下面需要判断
double currentX =x, currentY =y;
/**如果读取的时候发生了写,则stampedLock的stamp属性值会变化,此时需要重读,
* 再重读的时候需要加读锁(并且重读时使用的应当是悲观的读锁,即阻塞写的读锁)
* 当然重读的时候还可以使用tryOptimisticRead,此时需要结合循环了,即类似CAS方式
* 读锁又重新返回一个stampe值*/
if (!stampedLock.validate(stamp)) {
stamp =stampedLock.readLock(); //读锁
try {
currentX =x;
currentY =y;
}finally{
stampedLock.unlockRead(stamp);//释放读锁
}
}
//读锁验证成功后才执行计算,即读的时候没有发生写
return Math.sqrt(currentX *currentX + currentY *currentY);
}
}
StampedLock的实现思想
在StampedLock中使用了CLH自旋锁,如果发生了读失败,不立刻把读线程挂起,锁当中维护了一个等待线程队列。
所有申请锁但是没有成功的线程都会记录到这个队列中,每一个节点(一个节点表示一个线程)保存一个标记位(locked),
用于判断当前线程是否已经释放锁。当一个未标记到队列中的线程试图获得锁时,会取得当前等待队列尾部的节点作为其前序节点,
并使用类似如下代码(一个空的死循环)判断前序节点是否已经成功的释放了锁:
while(pred.locked){ }
解释:pred表示当前试图获取锁的线程的前序节点,如果前序节点没有释放锁,则当前线程就执行该空循环并不断判断前序节点的锁释放,
即类似一个自旋锁的效果,避免被系统挂起。当循环一定次数后,前序节点还没有释放锁,则当前线程就被挂起而不再自旋,
因为空的死循环执行太多次比挂起更消耗资源。
- Java8对读写锁的改进:StampedLock
- 《Java高并发程序设计》学习 --6.6 读写锁的改进:StampedLock
- java8-StampedLock
- java8中对ConcurrentHashMap的改进
- JAVA8 JDK 对字符串连接的改进
- Java8---4.对HashMap和ConcurrentHashMap的改进
- Java并发编程札记-(四)JUC锁-07读写锁的升级—StampedLock
- java8改进的接口
- java8改进的接口:
- Java8改进的接口
- java8中concurrentHashmap的改进
- Java 8的StampedLock
- StampedLock的使用
- StampedLock的简单用法
- StampedLock
- Java8的改进和新的特性
- java8改进的HashMap和Hashtable类
- java8改进的接口(一)
- 如何完美适配iPhone4、5、6尺寸和字体问题
- 将PC网站转化为手机自适应网页或者自己制作手机自适应网页其实很简单,可以利用meta标签声明。
- NYOJ 82 - 迷宫寻宝(一)
- 部分知识架构
- 蓝宙ARM仿真器固件烧写说明
- Java8对读写锁的改进:StampedLock
- |Tyvj|动态规划|P1004 滑雪
- android之两种设置全屏或者无标题的方法
- 斐波那契博弈
- 乘积最大vijosp1037ti
- HD--1285 确定比赛名次
- 判断子串
- memcache原理
- osg入门答疑