一文详解读写锁_C++ 读写锁

一文详解读写锁_C++ 读写锁作者|磊哥来源|Java面试真题解析(ID:aimianshi666)转载请联系授权(微信ID:GG_Stone)读写锁(Readers-WriterLock)顾名思义是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,因为读操作本身是线程安全的,而写锁则是互斥锁,不允许多个线程同时获得写锁,并且写操作和读操作也是互斥的。总结来说,读写锁的特点是:读读…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

15bf32c1f015a3c22166d0809a0512c9.png

作者 | 磊哥

来源 | Java面试真题解析(ID:aimianshi666)

转载请联系授权(微信ID:GG_Stone)

读写锁(Readers-Writer Lock)顾名思义是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,因为读操作本身是线程安全的,而写锁则是互斥锁,不允许多个线程同时获得写锁,并且写操作和读操作也是互斥的。总结来说,读写锁的特点是:读读不互斥、读写互斥、写写互斥

1.读写锁使用

在 Java 语言中,读写锁是使用 ReentrantReadWriteLock 类来实现的,其中:

  • ReentrantReadWriteLock.ReadLock 表示读锁,它提供了 lock 方法进行加锁、unlock 方法进行解锁。

  • ReentrantReadWriteLock.WriteLock 表示写锁,它提供了 lock 方法进行加锁、unlock 方法进行解锁。

它的基础使用如下代码所示:

// 创建读写锁
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 获得读锁
final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
// 获得写锁
final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
// 读锁使用
readLock.lock();
try {
    // 业务代码...
} finally {
    readLock.unlock();
}
// 写锁使用
writeLock.lock();
try {
    // 业务代码...
} finally {
    writeLock.unlock();
}

1.1 读读不互斥

多个线程可以同时获取到读锁,称之为读读不互斥,如下代码所示:

// 创建读写锁
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 创建读锁
final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
Thread t1 = new Thread(() -> {
    readLock.lock();
    try {
        System.out.println("[t1]得到读锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t1]释放读锁.");
        readLock.unlock();
    }
});
t1.start();
Thread t2 = new Thread(() -> {
    readLock.lock();
    try {
        System.out.println("[t2]得到读锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t2]释放读锁.");
        readLock.unlock();
    }
});
t2.start();

以上程序执行结果如下:9050939ce5933edafe2299065f2d6145.png

1.2 读写互斥

读锁和写锁同时使用是互斥的(也就是不能同时获得),这称之为读写互斥,如下代码所示:

// 创建读写锁
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 创建读锁
final ReentrantReadWriteLock.ReadLock readLock = readWriteLock.readLock();
// 创建写锁
final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
// 使用读锁
Thread t1 = new Thread(() -> {
    readLock.lock();
    try {
        System.out.println("[t1]得到读锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t1]释放读锁.");
        readLock.unlock();
    }
});
t1.start();
// 使用写锁
Thread t2 = new Thread(() -> {
    writeLock.lock();
    try {
        System.out.println("[t2]得到写锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t2]释放写锁.");
        writeLock.unlock();
    }
});
t2.start();

以上程序执行结果如下:85327dff0b99e54c283364bbb7301f53.png

1.3 写写互斥

多个线程同时使用写锁也是互斥的,这称之为写写互斥,如下代码所示:

// 创建读写锁
final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
// 创建写锁
final ReentrantReadWriteLock.WriteLock writeLock = readWriteLock.writeLock();
Thread t1 = new Thread(() -> {
    writeLock.lock();
    try {
        System.out.println("[t1]得到写锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t1]释放写锁.");
        writeLock.unlock();
    }
});
t1.start();

Thread t2 = new Thread(() -> {
    writeLock.lock();
    try {
        System.out.println("[t2]得到写锁.");
        Thread.sleep(3000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        System.out.println("[t2]释放写锁.");
        writeLock.unlock();
    }
});
t2.start();

以上程序执行结果如下:5ad33501c62a467615563d95e9687a75.png

2.优点分析

  1. 提高了程序执行性能:多个读锁可以同时执行,相比于普通锁在任何情况下都要排队执行来说,读写锁提高了程序的执行性能。

  2. 避免读到临时数据:读锁和写锁是互斥排队执行的,这样可以保证了读取操作不会读到写了一半的临时数据。

3.适用场景

读写锁适合多读少写的业务场景,此时读写锁的优势最大。

总结

读写锁是一把锁分为两部分:读锁和写锁,其中读锁允许多个线程同时获得,而写锁则是互斥锁。它的完整规则是:读读不互斥、读写互斥、写写互斥。它适用于多读的业务场景,使用它可以有效的提高程序的执行性能,也能避免读取到操作了一半的临时数据。

是非审之于己,毁誉听之于人,得失安之于数。

公众号:Java面试真题解析

面试合集:https://gitee.com/mydb/interview

ba04013fbaa0308440acbe48d7f237dc.gif

往期推荐

34fac227a81c77080e56780ed5087fc5.png

面试突击44:volatile 有什么用?


d426463bc36eee68bf9cbdfefd0f11fc.png

面试突击43:lock、tryLock、lockInterruptibly有什么区别?


2a23d136b8bc04fbbd0babb52b57cb73.png

面试突击42:synchronized和ReentrantLock有什么区别?


2286f220dd796f3600738bcd769a7386.gif

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/169993.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 微型计算机原理与接口技术网课_微型计算机原理与接口技术周荷琴

    微型计算机原理与接口技术网课_微型计算机原理与接口技术周荷琴微型计算机组成原理课程内容介绍第一章微型计算机基础第二章80X80微型处理器第三章汇编语言指令集第四章汇编语言程序设计第五章输入/输出系统第六章中断系统第七章微型计算机系统串行通讯第八章并行I/O接口第九章可编程定时/计数器课程意义汇编语言接口技术学习目标本笔记的视频,源自中国大学MOOC,南京邮电大学的微型计算机原理与接口技术。课程内容介绍第一章微型计算机基础这一章将…

    2022年10月2日
    0
  • ASP Session 对象

    ASP Session 对象Session对象用于存储关于某个用户会话(session)的信息,或者修改相关的设置。存储在session对象中的变量掌握着单一用户的信息,同时这些信息对于页面中的所有页面都是可用的。实例设置并返回LCID本例演示”LCID”属性。此属性设置并返回一个指明位置或者地区的整数。类似于日期、时间以及货币等内容都要根据位置或者地区来显示。返回SessionID本例演示”Ses

    2022年7月25日
    3
  • fedora 12 QQ 的安装使用过程「建议收藏」

    fedora 12 QQ 的安装使用过程「建议收藏」一 下载地址:http://im.qq.com/qq/linux/download.shtml  由于装的是fedora  12于是下linuxqq-v1.0.2-beta1.i386.rmp直接双击安装就可以了。安装完后,应用程序出现在Internet下的腾讯QQ。二 成功登录后,不小心按了最小化后,郁闷的发现找不到qq图标。其实解决很简单,在面板上右击,选择添加到面板

    2022年9月2日
    3
  • FusionChartsFree的简单用法[通俗易懂]

    FusionChartsFree的简单用法[通俗易懂]  今天发现个不错的显示图表的东西—-FusionChartsFree,有免费版的,有收费版的,免费版的我用着就不错。收费的可能更好一点儿。  看了看官方提供的例子,我是在JSP中使用,想到一个简单的用法,贴在下面:[code="html"]结果显示 FusionCharts. varchart…

    2022年7月13日
    14
  • 执行pip 命令出现Could not install packages due to an EnvironmentError错误的解决办法「建议收藏」

    执行pip 命令出现Could not install packages due to an EnvironmentError错误的解决办法「建议收藏」今天想安装一个pyspider,但是却出现了下图的错误因为环境的错误导致的原因,嗯…….搜了一下,只需把命令改为pipinstall–userpyspider就可以了。网上的回答是直接这样就行了,但是我的却出现了另一个问题。这个包是安装成功了,但是调用时输入pyspiderall,却返回了pyspider不是内部或外部命令的提示,注意看安装成功之前有几行…

    2022年9月13日
    0
  • sublime3激活码-激活码分享

    (sublime3激活码)2021最新分享一个能用的的激活码出来,希望能帮到需要激活的朋友。目前这个是能用的,但是用的人多了之后也会失效,会不定时更新的,大家持续关注此网站~https://javaforall.net/100143.htmlIntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,上面是详细链接哦~ML…

    2022年3月21日
    40

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号