传统版案例
package com.bilibili.juc.rwlock;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.StampedLock;
/**
* @auther zzyy
*
* StampedLock = ReentrantReadWriteLock + 读的过程中也允许获取写锁介入
*/
public class StampedLockDemo
{
static int number = 37;
static StampedLock stampedLock = new StampedLock();
public void write()
{
long stamp = stampedLock.writeLock();
System.out.println(Thread.currentThread().getName()+"\t"+"写线程准备修改");
try
{
number = number + 13;
}finally {
stampedLock.unlockWrite(stamp);
}
System.out.println(Thread.currentThread().getName()+"\t"+"写线程结束修改");
}
//悲观读,读没有完成时候写锁无法获得锁
public void read()
{
long stamp = stampedLock.readLock();
System.out.println(Thread.currentThread().getName()+"\t"+" come in readlock code block,4 seconds continue...");
for (int i = 0; i < 4; i++) {
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName()+"\t"+" 正在读取中......");
}
try
{
int result = number;
System.out.println(Thread.currentThread().getName()+"\t"+" 获得成员变量值result:"+result);
System.out.println("读锁的时候,写锁无法介入");
}finally {
stampedLock.unlockRead(stamp);
}
}
public static void main(String[] args)
{
StampedLockDemo resource = new StampedLockDemo();
//传统版
new Thread(() -> {
resource.read();
},"readThread").start();
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); }
new Thread(() -> {
System.out.println(Thread.currentThread().getName()+"\t"+"----come in");
resource.write();
},"writeThread").start();
//暂停几秒钟线程
try { TimeUnit.SECONDS.sleep(4); } catch (InterruptedException e) { e.printStackTrace(); }
System.out.println(Thread.currentThread().getName()+"\t"+"number:" +number);
}
}
输出:
readThread come in readlock code block,4 seconds continue...
readThread 正在读取中......
writeThread ----come in
readThread 正在读取中......
readThread 正在读取中......
readThread 正在读取中......
readThread 获得成员变量值result:37
读锁的时候,写锁无法介入
writeThread 写线程准备修改
writeThread 写线程结束修改
main number:50
升级版
package com.bilibili.juc.rwlock; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.StampedLock; /** * @auther zzyy * * StampedLock = ReentrantReadWriteLock + 读的过程中也允许获取写锁介入 */ public class StampedLockDemo { static int number = 37; static StampedLock stampedLock = new StampedLock(); public void write() { long stamp = stampedLock.writeLock(); System.out.println(Thread.currentThread().getName()+"\t"+"写线程准备修改"); try { number = number + 13; }finally { stampedLock.unlockWrite(stamp); } System.out.println(Thread.currentThread().getName()+"\t"+"写线程结束修改"); } //乐观读,读的过程中也允许获取写锁介入 public void tryOptimisticRead() { long stamp = stampedLock.tryOptimisticRead(); int result = number; //故意间隔4秒钟,很乐观认为读取中没有其它线程修改过number值,具体靠判断 System.out.println("4秒前stampedLock.validate方法值(true无修改,false有修改)"+"\t"+stampedLock.validate(stamp)); for (int i = 0; i < 4; i++) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"\t"+"正在读取... "+i+" 秒" + "后stampedLock.validate方法值(true无修改,false有修改)"+"\t"+stampedLock.validate(stamp)); } if(!stampedLock.validate(stamp)) { System.out.println("有人修改过------有写操作"); stamp = stampedLock.readLock();//从乐观读 升级为 悲观读 try { System.out.println("从乐观读 升级为 悲观读"); result = number; System.out.println("重新悲观读后result:"+result); }finally { stampedLock.unlockRead(stamp); } } System.out.println(Thread.currentThread().getName()+"\t"+" finally value: "+result); } public static void main(String[] args) { StampedLockDemo resource = new StampedLockDemo(); new Thread(() -> { resource.tryOptimisticRead(); },"readThread").start(); //暂停2秒钟线程,读过程可以写介入,演示 try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(() -> { System.out.println(Thread.currentThread().getName()+"\t"+"----come in"); resource.write(); },"writeThread").start(); } } 输出: 4秒前stampedLock.validate方法值(true无修改,false有修改) true readThread 正在读取... 0 秒后stampedLock.validate方法值(true无修改,false有修改) true writeThread ----come in writeThread 写线程准备修改 writeThread 写线程结束修改 readThread 正在读取... 1 秒后stampedLock.validate方法值(true无修改,false有修改) false readThread 正在读取... 2 秒后stampedLock.validate方法值(true无修改,false有修改) false readThread 正在读取... 3 秒后stampedLock.validate方法值(true无修改,false有修改) false 有人修改过------有写操作 从乐观读 升级为 悲观读 重新悲观读后result:50 readThread finally value: 50 Process finished with exit code 0