学习之Java学习

JAVA多线程并发--使用ReadWriteLock实现读写锁

2021-06-24  本文已影响0人  砌月东谷

JUC提供了专门的读写锁ReadWriteLock,可以分别用于对读操作或者写操作进行加锁,在源码中主要定义了两个接口,分别是readLock和writeLock:

readLock 读锁

加了读锁的资源,可以在没有写锁的时候被多个线程共享,换句话说,如果线程1获取了读锁,那么此时可能存在两种状态:
  1. 如果2线程要申请写锁,则2线程会一直等待1线程释放读锁
  2. 如果2线程要申请读锁,则2线程可以直接读取资源,也就是说读锁是共享锁

writeLock 写锁

写锁是独占锁,加了写锁的资源,不能再被其他线程读或者写,如果1线程已经获取了写锁,那么无论2线程要申请写锁或者读锁,都必须等待1线程释放写锁

第一种情况,当1线程获取了读锁后,2线程也可以获取读锁

/**
         * 第一种情况,当1线程获取了读锁后,2线程也可以获取读锁
         */
        //读写锁的实现类
        ReentrantReadWriteLock reentrantReadWriteLock=new ReentrantReadWriteLock();
        new Thread(()->{
            reentrantReadWriteLock.readLock().lock();

            for(int i=0;i<100000;i++){
                System.out.println(Thread.currentThread().getName()+"正在进行读操作");
            }
            System.out.println(Thread.currentThread().getName()+"读操作完毕");
            reentrantReadWriteLock.readLock().unlock();



        }).start();

        new Thread(()->{
            reentrantReadWriteLock.readLock().lock();

            for(int i=0;i<100000;i++){
                System.out.println(Thread.currentThread().getName()+"正在进行读操作");
            }
            System.out.println(Thread.currentThread().getName()+"读操作完毕");
            reentrantReadWriteLock.readLock().unlock();

        }).start();

运行截图:


image-20210624100526881.png

可以看到线程1和线程2交替执行

第二种情况 当线程1获取了读锁后,线程2获取写锁

//读写锁的实现类
        ReentrantReadWriteLock reentrantReadWriteLock=new ReentrantReadWriteLock();
        new Thread(()->{
            reentrantReadWriteLock.readLock().lock();

            for(int i=0;i<100000;i++){
                System.out.println(Thread.currentThread().getName()+"正在进行读操作");
            }
            System.out.println(Thread.currentThread().getName()+"读操作完毕");
            reentrantReadWriteLock.readLock().unlock();



        }).start();

        new Thread(()->{
            reentrantReadWriteLock.writeLock().lock();

            for(int i=0;i<100000;i++){
                System.out.println(Thread.currentThread().getName()+"正在进行写操作");
            }
            System.out.println(Thread.currentThread().getName()+"写操作完毕");
            reentrantReadWriteLock.writeLock().unlock();

        }).start();

运行截图:


image-20210624100830746.png

线程1获取了读锁,线程2尝试获取写锁,需要等线程1释放读锁后

第三种情况 当线程1获取了写锁,线程2获取写锁或者读锁读都需要等待线程1释放写锁

/**
         * 第三种情况,当线程1先获取写锁,不管线程2获取读锁还是写锁都要先等线程1释放写锁
         */

        //读写锁的实现类
        ReentrantReadWriteLock reentrantReadWriteLock=new ReentrantReadWriteLock();
        new Thread(()->{
            reentrantReadWriteLock.writeLock().lock();

            for(int i=0;i<100;i++){
                System.out.println(Thread.currentThread().getName()+"正在进行写操作");
            }
            System.out.println(Thread.currentThread().getName()+"写操作完毕");
            reentrantReadWriteLock.writeLock().unlock();



        }).start();

        new Thread(()->{
            reentrantReadWriteLock.readLock().lock();

            for(int i=0;i<100;i++){
                System.out.println(Thread.currentThread().getName()+"正在进行读操作");
            }
            System.out.println(Thread.currentThread().getName()+"读操作完毕");
            reentrantReadWriteLock.readLock().unlock();

        }).start();

运行截图:


image-20210624101225906.png
上一篇下一篇

猜你喜欢

热点阅读