StampedLock比读写锁更快的锁
在JDK8的年代,出现了一名绝世高手,他在读多写少速度大会上击败了老牌的昔日冠军读写锁。
他就是StampedLock。
出现的情况,更好的解决并发下的读多写少,提高性能。
StampedLock支持三种模式,分别是:写锁,悲观读锁,和乐观读。其中,他拥有着读写锁相近的功力,不同的是:StampedLock的写锁和悲观读锁加锁成功之后,都会返回一个long类型的stamp,然后解锁的时候,需要传入这个stamp。
为什么StampedLock性能之所以比读写锁好,原因在于StampedLock支持乐观读的方式,而读写锁支持多个线程同时读,所有的写操作会被阻塞,而StampedLock提供的乐观读,是允许一个线程能获取写锁的,也就是说不是所有的写操作都被阻塞,这就是关键的地方。
同时有需要注意的事项的地方:
StampedLock的功能是读写锁的子集。所以StampedLock适用场景就是单纯的读多写少。
StampedLock并且是不可重入的。即需要特别注意
StampedLock的悲观读锁,写锁不支持条件变量。
如果某个线程阻塞在读锁或者写锁上,如果此时调用了这个线程的interrupt方法,会导致这个线程所在的cpu100%,所以处理这类情况,最好一定不要调用中断操作,如果需要支持中断,一定使用可中断的悲观读锁的readLockInterruptibly() 和写锁 writeLockInterruptibly()。规则。
赴上自己的demo:
package com.hnist.lzn.thread;
public class StampedLock {
private final java.util.concurrent.locks.StampedLock sl = new java.util.concurrent.locks.StampedLock();
private int x;
//写锁
void modify(int a){
long stamp = sl.readLock();
try{
setX(a);
int ax = getX();
System.out.println("----------------------------------------------------写互斥,修改后a:"+ax);
}finally {
sl.unlock(stamp);
}
}
//读模板
void read(){
long stamp = sl.tryOptimisticRead();
int num = getX();
//检验stamp
if (!sl.validate(stamp)){
//无效升级为悲观读锁
stamp = sl.readLock();
try {
num = getX();
System.out.println("*****************************悲观读数据");
}finally {
sl.unlock(stamp);
}
}
//都是操作变量的业务
System.out.println("通过读方法:"+num);
}
public void setX(int x){
this.x = x;
}
public int getX(){
return x;
}
public static void main(String[] args) throws InterruptedException {
StampedLock stampedLock = new StampedLock();
Thread th1 = new Thread(()->{
//读线程
while(true){
stampedLock.read();
}
});
Thread th4 = new Thread(()->{
//读线程
while(true){
stampedLock.read();
}
});
Thread th2 = new Thread(()->{
//写线程
int i = 9999999;
while(true) {
stampedLock.modify(i--);
}
});
Thread th3 = new Thread(()->{
//写线程
int i = 1;
while(true) {
stampedLock.modify(i++);
}
});
//th2.start();
th3.start();
th4.start();
//Thread.sleep(200);
th1.start();
//Thread.sleep(1000);
// Thread.sleep(1000);
}
}
还没有评论,来说两句吧...