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 支持锁降级,但是!! 并不会自动释放写锁,需要显式的释放写锁,否则其它线程永远获取不到写锁

相关内容

热门资讯

保存时出现了1个错误,导致这篇... 当保存文章时出现错误时,可以通过以下步骤解决问题:查看错误信息:查看错误提示信息可以帮助我们了解具体...
汇川伺服电机位置控制模式参数配... 1. 基本控制参数设置 1)设置位置控制模式   2)绝对值位置线性模...
不能访问光猫的的管理页面 光猫是现代家庭宽带网络的重要组成部分,它可以提供高速稳定的网络连接。但是,有时候我们会遇到不能访问光...
表格中数据未显示 当表格中的数据未显示时,可能是由于以下几个原因导致的:HTML代码问题:检查表格的HTML代码是否正...
本地主机上的图像未显示 问题描述:在本地主机上显示图像时,图像未能正常显示。解决方法:以下是一些可能的解决方法,具体取决于问...
表格列调整大小出现问题 问题描述:表格列调整大小出现问题,无法正常调整列宽。解决方法:检查表格的布局方式是否正确。确保表格使...
不一致的条件格式 要解决不一致的条件格式问题,可以按照以下步骤进行:确定条件格式的规则:首先,需要明确条件格式的规则是...
Android|无法访问或保存... 这个问题可能是由于权限设置不正确导致的。您需要在应用程序清单文件中添加以下代码来请求适当的权限:此外...
【NI Multisim 14...   目录 序言 一、工具栏 🍊1.“标准”工具栏 🍊 2.视图工具...
银河麒麟V10SP1高级服务器... 银河麒麟高级服务器操作系统简介: 银河麒麟高级服务器操作系统V10是针对企业级关键业务...