ReentrantReadWriteLock笔记(一) -- 基本使用

先定义三个Runnable


//读操作
 Runnable readTask = () -> {
     lock.readLock().lock();
     try {
         System.out.println(Thread.currentThread().getName() + "获得读锁,开始读操作");
         try {
             Thread.sleep(3000);
             System.out.println(Thread.currentThread().getName() + "读操作完毕");
         } catch (InterruptedException e) {
             System.out.println(Thread.currentThread().getName() + "读操作被中断");
         }
     } finally {
         lock.readLock().unlock();
     }
 };
 //写操作
 Runnable writeTask = ()->{
     lock.writeLock().lock();
     try {
         System.out.println(Thread.currentThread().getName() + "获得写锁,开始写操作");
         try {
             Thread.sleep(3000);
             System.out.println(Thread.currentThread().getName() + "写操作完毕");
         } catch (InterruptedException e) {
             System.out.println(Thread.currentThread().getName() + "写操作被中断");
         }
     }finally {
         lock.writeLock().unlock();
     }
 };
 //写+读操作
 Runnable writeReadTask = ()->{
     lock.writeLock().lock();
     try {
         System.out.println(Thread.currentThread().getName() + "获得写锁,开始写操作");
         lock.readLock().lock();
         try {
             System.out.println(Thread.currentThread().getName() + "获得写+读锁");
         }finally {
             lock.readLock().unlock();
         }
         try {
             Thread.sleep(3000);
             System.out.println(Thread.currentThread().getName() + "写操作完毕");
         } catch (InterruptedException e) {
             System.out.println(Thread.currentThread().getName() + "写操作被中断");
         }
     }finally {
         lock.writeLock().unlock();
     }
 };

下面开始测试
测试1:

new Thread(readTask, "t1").start();
new Thread(readTask, "t2").start();
Thread.sleep(100);
new Thread(writeTask, "t3").start();

输出 :
测试1

测试2:

new Thread(writeTask, "t3").start();
Thread.sleep(100);
new Thread(readTask, "t1").start();
new Thread(readTask, "t2").start();

输出 :
测试2

测试3:

new Thread(writeReadTask, "t1").start();

输出 :
测试3

总结:

  • 读锁是共享的,读过程中,其他线程可以获得读锁,但不能写锁
  • 写锁是排它的,写过程中,其他线程不能读写
  • 线程获得写锁后,还可以获得读锁

补充: 后面看了ReadLock的源码发现这么个情况

new Thread(readTask, "t1").start();
Thread.sleep(100);
new Thread(writeTask, "t3").start();
Thread.sleep(100);
new Thread(readTask, "t2").start();

输出

t1获得读锁,开始读操作
t1读操作完毕
t3获得写锁,开始写操作
t3写操作完毕
t2获得读锁,开始读操作
t2读操作完毕

想表达的是,当一个线程A获得读锁,然后来一个线程B来请求写锁,这时B会失败入sync队列,接着又来一个线程C请求读锁,这时C也会失败,进入sync队列排在B后面,所以输出就像上面那样了。

猜你喜欢

转载自blog.csdn.net/seasonLai/article/details/82559053