当前位置: 首页 > 后端技术 > Java

访谈突击45:为什么要用读写锁?它的优点是什么?

时间:2023-04-01 14:17:25 Java

读者-写入锁(Readers-WriterLock),顾名思义,就是一种锁,分为读锁和写锁两部分。读锁允许多个线程同时获取,因为读操作本身是线程安全的,而写锁是互斥锁,不允许多个线程同时获取写锁,写操作和读操作也是互斥的。总结一下,读写锁的特点是:读和读不互斥,读和写互斥,写和写互斥。1.Java语言中使用了读写锁。读写锁使用ReentrantReadWriteLock类实现,其中:ReentrantReadWriteLock.ReadLock代表读锁,提供lock方法用于加锁,unlock方法用于解锁。ReentrantReadWriteLock.WriteLock代表一个写锁,提供lock方法进行加锁,unlock方法进行解锁。它的基本使用如下代码所示://创建一个读写锁finalReentrantReadWriteLockreadWriteLock=newReentrantReadWriteLock();//获取一个读锁finalReentrantReadWriteLock.ReadLockreadLock=readWriteLock.readLock();//获取一个写锁lockfinalReentrantReadWriteLock.WriteLockwriteLock=readWriteLock.writeLock();//读锁使用readLock.lock();try{//业务代码...}finally{readLock.unlock();}//写锁使用writeLock。lock();try{//业务代码...}finally{writeLock.unlock();}1.1读与读不互斥多个线程可以同时获取读锁,称为读与读不互斥互斥,如下代码所示://创建读写锁finalReentrantReadWriteLockreadWriteLock=newReentrantReadWriteLock();//创建读写锁finalReentrantReadWriteLock.ReadLockreadLock=readWriteLock.readLock();Threadt1=newThread(()->{readLock.lock();try{System.out.println("[t1]获得读锁。");线程.睡眠(3000);}catch(InterruptedExceptione){e.printStackTrace();}finally{System.out.println("[t1]释放读锁。");readLock.unlock();}});t1.start();Threadt2=newThread(()-&g吨;{readLock.lock();try{System.out.println("[t2]获得了读锁。");线程.睡眠(3000);}catch(InterruptedExceptione){e.printStackTrace();}finally{System.out.println("[t2]释放读锁。");readLock.unlock();}});t2.start();上述程序的执行结果如下:1.2读写互斥读锁和写锁同时使用是互斥的(即不能同时获取),称为读写互斥,如如下代码所示://创建读写锁finalReentrantReadWriteLockreadWriteLock=newReentrantReadWriteLock();//创建读写锁finalReentrantReadWriteLock.ReadLockreadLock=readWriteLock.readLock();//创建写锁finalReentrantReadWriteLock.WriteLockwriteLock=readWriteLock.writeLock();//使用读锁Threadt1=newThread(()->{readLock.lock();try{System.out.println("[t1]获得读锁。");Thread.sleep(3000);}catch(InterruptedExceptione){e.printStackTrace();}finally{System.out.println("[t1]释放读锁。");readLock.unlock();}});t1.start();//使用写锁Threadt2=newThread(()->{writeLock.lock();try{System.out.println("[t2]获得写锁。");线程.睡眠(3000);}catch(InterruptedExceptione){e.printStackTrace();}最后{系统。out.println("[t2]释放写锁。");writeLock.unlock();}});t2.开始();上面程序的执行结果如下:互斥,这个叫做写写互斥,如下代码所示://创建读写锁finalReentrantReadWriteLockreadWriteLock=newReentrantReadWriteLock();//创建写锁finalReentrantReadWriteLock.WriteLockwriteLock=readWriteLock.writeLock();Threadt1=newThread(()->{writeLock.lock();try{System.out.println("[t1]gotwritelock.");Thread.sleep(3000);}catch(InterruptedExceptione){e.printStackTrace();}finally{System.out.println("[t1]释放写锁。");writeLock.unlock();}});t1.start();Threadt2=newThread(()->{writeLock.lock();尝试{System.out.println("[t2]获得写锁。");Thread.sleep(3000);}catch(InterruptedExceptione){e.printStackTrace();}finally{System.out.println("[t2]释放写锁。");writeLock.unlock();}});t2.start();以上程序执行结果如下:2.优势分析提高程序执行性能:可以同时执行多个读锁。相对于任何情况下都必须排队执行的普通锁,读写锁提高了程序执行性能,避免读取临时数据:读锁和写锁在互斥队列中执行,保证了读操作不会读到一半-写入的临时数据。3、适用场景读写锁适用于读多写少的业务场景。这时候读写锁就具有最大的优势。总结读写锁是一种锁,分为读锁和写锁两部分。读锁允许多个线程同时获取,而写锁是互斥锁。它的完整规则是:read与read不互斥,read与write互斥,write与write互斥。适用于多读业务场景。使用它可以有效的提高程序的执行性能,也可以避免读取到半操作的临时数据。判断是非在自己,名誉在别人,得失在人数。公众号:Java面试真题分析面试合集:https://gitee.com/mydb/interview