美文网首页学习之Java学习
JAVA多线程并发--使用ReadWriteLock实现读写锁

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

作者: 砌月东谷 | 来源:发表于2021-06-24 10:18 被阅读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

    相关文章

      网友评论

        本文标题:JAVA多线程并发--使用ReadWriteLock实现读写锁

        本文链接:https://www.haomeiwen.com/subject/durwyltx.html