java读写锁ReentrantReadWriteLock使用

为什么要使用读写锁

读写锁采用读锁与写锁分离等待方法,能够更加细粒度进行代码同步。提高代码并发量。如代码都是进行读操作时,多线程读取并不会带来线程安全问题,若加入锁,则会带来没必要的资源浪费,影响代码运行速度。引入读写锁能解决此问题

读写锁遵循规则

  1. 当读锁被获取时,写锁无法被获取,而读锁能正常被获取
  2. 当写锁被获取时,读锁和写锁都无法被获取

代码实现

线程资源类

class Readwrite {
          
   
    private volatile int count = 0;
    ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    public void write() {
          
   
        readWriteLock.writeLock().lock();
        System.out.println("获取写锁");
        count++;
        System.out.println("执行了写操作count = " + count);
        try {
          
   
            Thread.sleep(1);
        } catch (Exception e) {
          
   
            e.printStackTrace();
        }
        System.out.println("解除写锁");
        readWriteLock.writeLock().unlock();
    }

    public void read() {
          
   
        readWriteLock.readLock().lock();
        System.out.println("获取读锁");
        System.out.println("执行了读操作count = " + count);
        try {
          
   
            Thread.sleep(1000);
        } catch (Exception e) {
          
   
            e.printStackTrace();
        }
        readWriteLock.readLock().unlock();
        System.out.println("解除读锁");
    }

}

测试方法:

public static void main(String[] args) {
          
   
        //创建一个核心线程数为5,最大线程数为10,非核心线程闲置6秒后进行回收,排队等待阻塞队列长度为3的线程池
        ExecutorService executorService = new ThreadPoolExecutor(5, 10, 1L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(3), Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy());


        Readwrite readwrite = new Readwrite();
        for (int i = 0; i < 5; i++) {
          
   
            executorService.execute(() -> {
          
   
                readwrite.read();
            });
        }

        for (int i = 0; i < 5; i++) {
          
   
            executorService.execute(() -> {
          
   
                readwrite.write();
            });
        }

    }

创建了5个读线程,5个写线程

可以看到在获取读锁被获取后,其他线程依然能正常获取,而在读锁被持有时,无法获取写锁,只有读锁被释放后,才能获取读锁;若写锁被持有,读锁也不能被获取。

经验分享 程序员 微信小程序 职场和发展