• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

java并发编程专题(七)—-(JUC)ReadWriteLock的用法

java 搞代码 4年前 (2022-01-09) 21次浏览 已收录 0个评论

前面我们已经分析过JUC包里面的Lock锁,ReentrantLock锁和semaphore信号量机制。Lock锁实现了比synchronized更灵活的锁机制,Reentrantlock是Lock的实现类,是一种可重入锁,都是每次只有一次线程对资源进行处理;semaphore实现了多个线程同时对一个资源的访问;今天我们要讲的ReadWriteLock锁将实现另外一种很重要的功能:读写分离锁。

假设你的程序中涉及到对一些共享资源的读和写操作,且写操作没有读操作那么频繁。在没有写操作的时候,两个线程同时读一个资源没有任何问题,所以应该允许多个线程能在同时读取共享资源。但是如果有一个线程想去写这些共享资源,就不应该再有其它线程对该资源进行读或写,也就是说:读-读能共存,读-写不能共存,写-写不能共存。这就需要一个读/写锁来解决这个问题。

ReadWriteLock简介

我们在JUC包可以看到ReadWriteLock是一个接口,他有一个实现类:ReentrantReadWriteLock,先让我们对读写访问资源的条件做个概述:

  • – 读取: 没有线程正在做写操作,且没有线程在请求写操作。
  • – 写入: 没有线程正在做读写操作。

如果某个线程想要读取资源,只要没有线程正在对该资源进行写操作且没有线程请求对该资源的写操作即可。同样当有线程想要写资源,但是此刻有线程正在读取资源,那么此刻写资源的操作是不能继续下去的。

我们来看一个例子:

public class ReadWriteLockTest2 {
  public static void main(String[] args) {
      final int threadCount = 2;
      final ExecutorService exService = Executors.newFixedThreadPool(threadCount);
      final ScoreBoard scoreBoard = new ScoreBoard();
      exService.execute(new ScoreUpdateThread(scoreBoard));
      exService.execute(new ScoreHealthThread(scoreBoard));
      exService.shutdown();
    }
  }

  class ScoreBoard {
    private boolean scoreUpdated = false;
    private int score = 0;
    String health = "不可用";
    final ReentrantReadWriteLock rrwl = new ReentrantReadWriteLock();

    public String getMatchHealth() {
      rrwl.readLock().lock();
      if (scoreUpdated) {
        rrwl.readLock().unlock();
        rrwl.writeLock().lock();
        try {
          if (scoreUpdated) {
            score = fetchScore();
            scoreUpdated = false;
          }
          rrwl.readLock().lock();
        } finally {
          rrwl.writeLock().unlock();
        }
      }
      try {
        if (score % 2 == 0) {
          health = "Bad Score";
        } else {
          health = "Good Score";
        }
      } finally {
        rrwl.readLock().unlock();
      }
      return health;
    }

    public void updateScore() {
      try {
        rrwl.writeLock().lock();
        scoreUpdated = true;
      } finally {
        rrwl.writeLock().unlock();
      }
    }

    private int fetchScore() {
      Calendar calender = Calendar.getInstance();
      return calender.get(Calendar.MILLISECOND);
    }
  }

  class ScoreHealthThread implements Runnable {
    private ScoreBoard scoreBoard;
    public ScoreHealthThread(ScoreBoard scoreTable) {
      this.scoreBoard = scoreTable;
    }
    @Override
    public void run() {
      for(int i= 0; i< 5; i++) {
        System.out.println("Match Health: "+ scoreBoard.getMatchHealth());
        try {
          Thread.sleep(2000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
  }

  class ScoreUpdateThread implements Runnable {
    private ScoreBoard scoreBoard;
    public ScoreUpdateThread(ScoreBoard scoreTable) {
      this.scoreBoard = scoreTable;
    }
    @Override
    public void run() {
      for(int i= 0; i < 5; i++) {
        System.out.println("Score Updated.");
        scoreBoard.updateScore();
        try {
          Thread.sleep(2000);
        } catch (InterruptedException e) {
          e.printStackTrace();
        }
      }
    }
<div>本文来源gaodai^.ma#com搞#代!码网</div>  }

搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:java并发编程专题(七)—-(JUC)ReadWriteLock的用法
喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址