一文详解读写锁_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

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

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

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Python中通过PyPDF2实现PDF添加水印

    Python中通过PyPDF2实现PDF添加水印场景PyPDF2是一个纯pythonPDF库,能够分割、合并、裁剪和转换PDF文件的页面。它还可以向PDF文件中添加自定义数据、查看选项和密码。它可以从PDF检索文本和元数据,还可以将整个文件合并在一起。PyPDF21.26.0文档:https://pythonhosted.org/PyPDF2/实现使用pip安装pypddf2新建文件夹waterPDF在…

  • vc++菜鸟教程_vc6.0使用教程详解

    vc++菜鸟教程_vc6.0使用教程详解怎样编写自己的VCL控件     用过Delphi的朋友们,大概对Delphi的最喜欢Delphi的不是他的强类型的pascal语法,而是强大的VCL控件,本人就是一位VCL控件的爱好者。    VCL控件的开源,给我们带来了享之不尽的好处。不像以前的ole控件以及ActiveX,你完全可以重写Delphhi标准控件,而且网上这方面的资源很多。    关于如何编写VCL控件,和多Delphi

  • Redis 6379 被攻击

    Redis 6379 被攻击Redis6379被攻击刚开始使用redis,把端口打开了,然后没有设置密码,导致被恶意攻击,这里记录一下。[root@realguo~]#redis-cli127.0.0.1:6379>keys*1)”backup2″2)”backup1″3)”backup4″4)”backup3″127.0.0.1:6379>getbackup1″\n\n\n*/2****rootcd1-fsSLhttp://zzhreceive.anondn

  • leetcode 三数之和_leetcode数组交集

    leetcode 三数之和_leetcode数组交集原题链接给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。注意:答案中不可以包含重复的三元组。示例 1:输入:nums = [-1,0,1,2,-1,-4]输出:[[-1,-1,2],[-1,0,1]]示例 2:输入:nums = []输出:[]示例 3:输入:nums = [0]输出:[] 提示:0 <= nums.length <= 300

  • 【mysql系列】细谈explain执行计划之“谜”

    【mysql系列】细谈explain执行计划之“谜”目录理论Part概念实践Partidselect_typetabletypepossible_keyskeykey_lenrefrowsfilteredExtra总结聊到mysql数据库的优化,大家基本都会谈论explain关键字,确认sql是否使用数据库表中建立的索引,然后讨论sql语句或者索引优化方案等等~,那本篇文章主要谈论一下explain的理解。主要分为理论和实践相结合。理论Part概念我们先了解一下explain语法和相关理论知识。语法:EXPLAINSELECTselect_o

    2022年10月31日
  • docker离线安装部署_ubuntu 离线安装docker

    docker离线安装部署_ubuntu 离线安装docker说明使用虚拟机真实模仿离线环境虚拟机系统为CentOS7正文下载Docker二进制文件(离线安装包):下载地址本文使用/x86_64/docker-17.12.1-ce.tgz,注意对应操作系统类型。通过FTP工具将docker-17.12.1-ce.tgz上传到服务器上解压安装包tarzxfdocker-17.12.1-ce.tgz将docker相关命令拷贝到/usr/bin,方便直接运行命令sudocpdocker/*/usr/bin/启动Docke

发表回复

您的电子邮箱地址不会被公开。

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