当前位置:   article > 正文

【140期】阿里技术经理问:ReadWriteLock 读写之间互斥吗?

java readwrite 读写有冲突吗

点击上方“Java精选”,选择“设为星标”

别问别人为什么,多问自己凭什么!

下方留言必回,有问必答!

每天 08:00 更新文章,每天进步一点点...

之前有网友去阿里面试被问及关于互斥锁的问题,下边分享一篇不错的文章,分析的挺有道理的。

开发中遇到并发的问题一般会用到锁,Synchronized存在明显的一个性能问题就是读与读之间互斥;

ReadWriteLock是JDK5中提供的读写分离锁。读写分离锁可以有效地帮助减少锁竞争,以提升系统的性能。

ReadWriteLock管理一组锁,一个是只读的锁,一个是写锁。

Java并发库中ReetrantReadWriteLock实现了ReadWriteLock接口并添加了可重入的特性。推荐:学习Java进阶资料,号内回复Java进阶资料,即可获取。

读写锁ReentrantReadWriteLock:读读共享,读写互斥,写写互斥; 读写锁维护了一对锁,一个读锁,一个写锁,通过分离读锁和写锁,使得并发性相比一般的排他锁有了很大提升。在读多写少的情况下,读写锁能够提供比排他锁更好的并发性和吞吐量。

39ab818cb65111791fd89431992de2a6.png

从源码中可以看出,读写锁中同样依赖队列同步器Sync(AQS)实现同步功能,而读写状态就是其同步器的同步状态。

下面从例子中来说明:读读共享,读写互斥,写写互斥

代码如下:

  1. public class ReentrantWriteReadLockTest {
  2.     ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
  3.     ReadLock readLock = lock.readLock();
  4.     WriteLock writeLock = lock.writeLock();
  5.     
  6.     public void read(){
  7.         try {
  8.             readLock.lock();
  9.             System.out.println("线程"+Thread.currentThread().getName()+"进入。。。");
  10.             Thread.sleep(3000);
  11.             System.out.println("线程"+Thread.currentThread().getName()+"退出。。。");
  12.         } catch (InterruptedException e) {
  13.             e.printStackTrace();
  14.         }finally{
  15.             readLock.unlock();
  16.         }
  17.     }
  18.     
  19.     public void write(){
  20.         try {
  21.             writeLock.lock();
  22.             System.out.println("线程"+Thread.currentThread().getName()+"进入。。。");
  23.             Thread.sleep(3000);
  24.             System.out.println("线程"+Thread.currentThread().getName()+"退出。。。");
  25.         } catch (InterruptedException e) {
  26.             e.printStackTrace();
  27.         }finally{
  28.             writeLock.unlock();
  29.         }
  30.     }
  31.     
  32.  
  33.     public static void main(String[] args) {
  34.         final ReentrantWriteReadLockTest wr = new ReentrantWriteReadLockTest();
  35.         Thread t1 = new Thread(new Runnable() {
  36.             public void run() {
  37.                 wr.read();
  38.             }
  39.         }, "t1");
  40.         Thread t2 = new Thread(new Runnable() {
  41.             public void run() {
  42.                 wr.read();
  43.             }
  44.         }, "t2");
  45.         Thread t3 = new Thread(new Runnable() {
  46.             public void run() {
  47.                 wr.write();
  48.             }
  49.         }, "t3");
  50.         Thread t4 = new Thread(new Runnable() {
  51.             public void run() {
  52.                 wr.write();
  53.             }
  54.         }, "t4");
  55.         
  56.         t1.start();
  57.         t2.start();
  58.         //t3.start();
  59.         //t4.start();
  60.     }
  61. }

当我们启动线程t1和t2时,结果如下:

f4a03349f5377998a77b52314af8e299.png

线程t1和t2可以同时进入,说明了读读共享

当我们启动线程t2和t3时,结果如下:

d5dd79d7b443e484bc7d5e340afb003e.png

一个线程必须等待另一个线程退出,才能进入,说明了读写互斥

当我们启动线程t3和t4时,结果如下:

6c4cbdf939cae5a69c6bf0fe92a35e9e.png

一个线程必须等待另一个线程退出,才能进入,说明了写写互斥

作者:一中晴哥威武

cnblogs.com/liuqing576598117/p/11168528.html

精品资料,超赞福利!

>>Java精选面试题<< - 小程序,3000+ 道面试题在线刷,最新、最全 Java 面试题!

416f2b6aa175af4023904481b2c8fea1.png

期往精选  点击标题可跳转

【132期】面试官:Java 8 数据过滤,removeIf 和 filter 有什么区别?

【133期】面试官:TCP 连接大量 TIME_WAIT 状态 ,对业务有什么影响?如何处理?

【134期】技术总监问:如何设计群聊消息的已读未读功能?

【135期】面试官问:为什么要合并 HTTP 请求,实现batch call?

【136期】面试官:Spring AOP、AspectJ、CGLIB ?它们有什么关系?

【137期】面试官问:RocketMQ 与 Kafka 对比,谈谈两者的差异?

【138期】手撸 websocket + netty 实时视频弹幕交互功能(Java版附源码)

【139期】面试官问:一般后端接口都测试什么?怎么测?

文章有帮助的话,在看,转发吧!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Gausst松鼠会/article/detail/588914
推荐阅读
相关标签
  

闽ICP备14008679号