该类自1.8加入,是为了进一步优化读性能,它的特点时在使用读锁,写锁时都必须配合【戳】使用
加解读锁
long stamp = lock.readLock();
lock.unlockRead(stamp);
加解写锁
long stamp = lock.writeLock();
lock.unlockWrite(stamp);
乐观读,StampedLock支持tryOptimisticRead()方法(乐观读),读取完毕之后需要做一次戳校验,如果校验通过,表示这期间确实没有写操作,数据可以安全使用,如果校验没有通过,需要重新获取读锁,保证数据安全。
long stamp = lock.tryOptimisticRead();
//验戳
if (!lock.validate(stamp)) {
//锁升级
}
那么是否能够取代ReentrantLock,不能,因为它有下面的缺点
StampedLock不支持条件变量
StampedLock不支持可重入
package com.sharing_model.juc;
import java.util.concurrent.locks.StampedLock;
/**
* 读写锁测试
*/
public class StampedLockTest {
public static void main(String[] args) throws InterruptedException {
DataContainerStamped dataContainer = new DataContainerStamped(1);
new Thread(() -> {
try {
dataContainer.read(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "t1").start();
Thread.sleep(500);
new Thread(() -> {
try {
dataContainer.read(0);
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
class DataContainerStamped {
private int data;
private final StampedLock lock = new StampedLock();
public DataContainerStamped(int data) {
this.data = data;
}
public int read(int readTime) throws InterruptedException {
long stamp = lock.tryOptimisticRead();
Thread.sleep(readTime);
if (lock.validate(stamp)) {
return data;
}
//锁升级
try {
stamp = lock.readLock();
Thread.sleep(readTime);
return data;
} finally {
lock.unlock(stamp);
}
}
public void write(int newData) {
long stamp = lock.writeLock();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock(stamp);
}
}
}