在加读锁之前,先尝试进行乐观读,根据获取的戳进行校验,若通过,则数据合法安全,否则升级锁为读锁,再进行相关操作。相关代码如下:
public class TestLock {
public static void main(String[] args) {
DataContainer<Long>dataContainer=new DataContainer<>(1000L);
new Thread(()->{
try {
dataContainer.read(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t1").start();
new Thread(()->{
try {
dataContainer.read(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t2").start();
new Thread(()->{
try {
dataContainer.write(1000L);
} catch (InterruptedException e) {
e.printStackTrace();
}
},"t3").start();
}
}
class DataContainer<T>{
private T Data;
private final StampedLock stampedLock=new StampedLock();
public DataContainer(T data) {
Data = data;
}
public T read(T readTime) throws InterruptedException {
long stamp=stampedLock.tryOptimisticRead();
System.out.println(Thread.currentThread().getName()+",尝试乐观读.."+stamp);
Thread.sleep((Long)readTime);
if(stampedLock.validate(stamp)){
System.out.println(Thread.currentThread().getName()+",读取完成"+stamp);
return Data;
}
//锁升级
stamp=stampedLock.readLock();
try{
System.out.println(Thread.currentThread().getName()+",获取读锁"+stamp+",time:"+System.currentTimeMillis());
Thread.sleep((Long)readTime);
System.out.println(Thread.currentThread().getName()+",读入完成"+stamp+",time:"+System.currentTimeMillis());
return Data;
}finally {
System.out.println(Thread.currentThread().getName()+",释放读锁"+stamp+",time:"+System.currentTimeMillis());
stampedLock.unlockRead(stamp);
}
}
public void write(T data) throws InterruptedException {
long stamp=stampedLock.writeLock();
System.out.println(Thread.currentThread().getName()+",获取写锁.."+stamp+",time:"+System.currentTimeMillis());
try{
Thread.sleep((Long)data);
this.Data=data;
}finally {
System.out.println(Thread.currentThread().getName()+",释放写锁..."+stamp+",time:"+System.currentTimeMillis());
stampedLock.unlockWrite(stamp);
}
}
}