Java中读写锁ReadWriteLock的使用案例和性能对比
创始人
2024-01-25 22:04:41
0

ReadWriteLock

  • ReadWriteLock介绍
  • 实例代码和性能对比
  • 使用场景以及注意事项
    • 锁降级

ReadWriteLock介绍

ReadWriteLock 被称为读写锁,通过读读不加锁的方式区分业务,从而提高效率

读写锁与ReentLock锁的效率对比
我们用如下代码进行一个简单的对比

非公平模式(默认)
当以非公平初始化时,读锁和写锁的获取的顺序是不确定的。非公平锁主张竞争获取,可能会延缓一个或多个读或写线程,但是会比公平锁有更高的吞吐量。
公平模式
当以公平模式初始化时,线程将会以队列的顺序获取锁。当当前线程释放锁后,等待时间最长的写锁线程就会被分配写锁;或者有一组读线程组等待时间比写线程长,那么这组读线程组将会被分配读锁。

实例代码和性能对比

建议看着demo自己敲一下,可能会发现很多新的问题,记忆也更牢固

package ReentrantLock和LongAdder;import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;/*** @program: solution* @description: 演示ReadWriteLock的使用* @author: Wang Hai Xin* @create: 2022-11-14 10:10**/
public class ReadWritLockT {/**/static ReentrantLock lock = new ReentrantLock();static int value = 0;/*读写锁,ReentrantReadWriteLock 是读写锁ReadWriteLock的一种实现*/static ReadWriteLock readWriteLock = new ReentrantReadWriteLock();/*可以通过 redLocke和writeLock分出两把锁使用*/static Lock read = readWriteLock.readLock();static Lock write = readWriteLock.writeLock();public static void main(String[] args) {Date date = new Date();SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");String format = simpleDateFormat.format(date);Runnable writeRunnable = () -> write(lock, 1);//        Runnable writeRunnable = () -> write(write, 1);Runnable readRunnable = () -> read(lock);
//
//        Runnable readRunnable = () -> read(read);ArrayList threads = new ArrayList<>();for (int i = 0; i < 18; i++) {threads.add(new Thread(readRunnable));}for (int i = 0; i < 2; i++) {threads.add(new Thread(writeRunnable));}for (int i = 0; i < threads.size(); i++) {threads.get(i).start();}for (int i = 0; i < threads.size(); i++) {try {threads.get(i).join();} catch (InterruptedException e) {throw new RuntimeException(e);}}System.out.println("ReentrantLock开始时间"+format);Date date1 = new Date();SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss SSS");String format1 = simpleDateFormat1.format(date1);System.out.println("ReentLock 结束时间:" + format1);}public static void read(Lock lock) {try {lock.lock();Thread.sleep(1000);System.out.println("读数据结束");} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}public static void write(Lock lock, int i) {try {lock.lock();Thread.sleep(1000);value += i;System.out.println("写操作完成");} catch (InterruptedException e) {throw new RuntimeException(e);} finally {lock.unlock();}}}

ReentrantLock运行结果

读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
写操作完成
写操作完成
ReentrantLock开始时间2022-11-14 10:46:20 217
ReentLock 结束时间:2022-11-14 10:46:40 476

使用ReentrantReadWriteLock运行的结果为

// Runnable writeRunnable = () -> write(lock, 1);
//
Runnable writeRunnable = () -> write(write, 1);
//
// Runnable readRunnable = () -> read(lock);
Runnable readRunnable = () -> read(read);

读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
读数据结束
写操作完成
写操作完成
ReentrantLock开始时间2022-11-14 10:48:45 604
ReentLock 结束时间:2022-11-14 10:48:48 701

可以看出 在特定条件下,ReentrantReadWritLock的效率要比Reentrantlock的效率高很多。

使用场景以及注意事项

使用场景应该很好想了,就是读多写少的场景可以使用.

笔者不太推荐使用,
因为维护起来会很麻烦,如果业务逻辑复杂,后来的人很有可能就在读的逻辑中操作了数据。

锁降级

要实现一个读写锁,需要考虑很多细节,其中之一就是锁升级和锁降级的问题。什么是升级和降级呢?

在不允许中间写入的情况下,写入锁可以降级为读锁吗?读锁是否可以升级为写锁,优先于其他等待的读取或写入操作?简言之就是说,锁降级:从写锁变成读锁;锁升级:从读锁变成写锁,ReadWriteLock是否支持呢?

ReadWriteLock 不支持锁升级

ReadWriteLock 支持锁降级,但是!! 并不会自动释放写锁,需要显式的释放写锁,否则其它线程永远获取不到写锁

相关内容

热门资讯

AWSECS:访问外部网络时出... 如果您在AWS ECS中部署了应用程序,并且该应用程序需要访问外部网络,但是无法正常访问,可能是因为...
AWSElasticBeans... 在Dockerfile中手动配置nginx反向代理。例如,在Dockerfile中添加以下代码:FR...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...
北信源内网安全管理卸载 北信源内网安全管理是一款网络安全管理软件,主要用于保护内网安全。在日常使用过程中,卸载该软件是一种常...
AWR报告解读 WORKLOAD REPOSITORY PDB report (PDB snapshots) AW...
AWS管理控制台菜单和权限 要在AWS管理控制台中创建菜单和权限,您可以使用AWS Identity and Access Ma...
​ToDesk 远程工具安装及... 目录 前言 ToDesk 优势 ToDesk 下载安装 ToDesk 功能展示 文件传输 设备链接 ...
群晖外网访问终极解决方法:IP... 写在前面的话 受够了群晖的quickconnet的小水管了,急需一个新的解决方法&#x...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
Azure构建流程(Power... 这可能是由于配置错误导致的问题。请检查构建流程任务中的“发布构建制品”步骤,确保正确配置了“Arti...