Java并发编程(10)-显式锁和读写锁

多线程 - 为什么要用读写锁?它有什么优点?以及使用案例 【为什么要用读写锁?它有什么优点?以及使用案例】 阅读详情


更多关于Java并发编程的文章请点击这里:Java并发编程实践(0)-目录页


在Java5.0之前,用于调节共享对象访问的机制只有synchronized和volatile。Java5.0之后提供了新的选择:ReentrantLock,即显式锁。显式锁与之前提过的synchronized的同步互斥 机制不太一样,ReentrantLock并不作为内部锁机制的替代,而是当内部锁机制有局限时可供选择的高级特性。
本文总结自《Java并发编程实践》 第十三章 显式锁 。

一、显式锁

1.1、什么是显式锁

在Java5.0之前,用于调节共享对象访问的机制只有synchronized和volatile。Java5.0之后提供了新的选择:ReentrantLock,即显式锁。显式锁与之前提过的synchronized的同步互斥 机制不太一样,ReentrantLock并不作为内部锁机制的替代,而是当内部锁机制有局限时可供选择的高级特性:

  • 1、显式锁可供开发者人工调控,不易出现同步锁的死锁问题
  • 2、显式锁是可轮询的、定时的以及可中断的锁获取操作、非快结构的加锁(对应于synchronized的加锁和释放都是在同一块代码块中)
1.2、Lock和ReentrantLock
  • Lock接口:
    Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作:
public interface Lock {
    void lock();
    void lockInterruptibly() throws InterruptedException;//可中断锁(在获取锁的时候可以响应中断)
    boolean tryLock();                    //轮询锁
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;//定时锁
    void unlock();  //释放锁
    Condition newCondition();
}
  • ReentrantLock类:
    ReentrantLock 是Lock的一个实现类,将由最近成功获得锁,并且还没有释放该锁的线程所拥有。此类的构造方法接受一个可选的公平 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间最长的线程。否则此锁将无法保证任何特定访问顺序。
1.3、如何使用显示锁

首先思考一下,为什么要使用显式锁呢?了解过synchronized同步锁的朋友应该明白,当A线程持有该锁,并且迟迟不能完成任务时,该锁将一直被A持有且不能释放,那么B线程就需要等待A释放锁,这会形成一个问题,即线程饥饿死锁。如以下代码:

public synchronized void function(){
            //doing something...
    }

但是,如果使用显式锁的话,我们可以人为地调控何时去获得锁,何时去释放锁,从而避免了死锁的发生,这就是使用显式锁的原因。

 Lock lock = new ReentrantLock();

        lock.lock();//由执行到该处的线程获得锁

        try{
            //doing something
            //捕获异常进行处理
        }finally {
            lock.unlock();//释放锁
        }

二、读写锁

2.1、为什么使用读写锁

ReentrantLock是一种标准的互斥锁,最多只有一个线程能拥有它;这样的实现是线程安全的,但是对读和写两种情况都进行了同步限制,那么在频繁读取时,会对性能造成不必要的浪费。所以,读写锁的出现缓解了这样的问题。读写锁(ReadWriteLock)的加锁策略允许多个同时存在的读者,但是只允许一个写者。

2.2、ReadWriteLock接口和ReentrantReadWriteLock实现类

特点允许多个线程同时读,允许一个线程写。

public interface ReadWriteLock {
    Lock readLock();
    Lock writeLock();
}
//ReentrantReadWriteLock是默认的非公平读写锁实现
ReentrantLock lock= new ReentrantReadWriteLock();
Lock readLock = lock.readLock();//获得读锁
Lock writeLock = lock.writeLock();//获得写锁
2.3、使用读写锁
public class ReadWriteMap<K,V> {
    //读写锁
    private ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
    //read lock
    private Lock readLock = readWriteLock.readLock();
    //write lock
    private Lock writeLock = readWriteLock.writeLock();
    //map
    private final Map<K,V> map ;
    //含参构造
    public ReadWriteMap(Map map){
        this.map = map;
    }

    //get方法,使用读锁
    public V get(K key){
        readLock.lock();//其他线程只读不写
        return map.get(key);
    }

    //put方法,使用写锁
    public void put(K key,V value){
        writeLock.lock();//其他线程都不能写
        map.put(key,value);
    }

}
基于Transformers库的BERT模型:一个文本情感分类的实例解析 简介 本文来讲述BERT应用的一个例子,采用预训练好的BERT模型来进行演示。BERT的库来源于Transformers,这是一个由PyTorch编写的库,其集成了多个NLP领域SOTA的模型,比如bert、gpt-2、transformer xl等,并且可以自由选择已经预训练好的模型参数,我们可以基于这些参数进行进一步的训练调试。 Part 1: 利用BERT基于特征的方式进行建模 1、任务与数... 阅读详情

相关推荐

高通Camera PDAF调试实战:从Type2到Type3的避坑指南与Log分析技巧

本文深入解析高通Camera平台PDAF调试实战,重点对比Type2与Type3的核心差异,提供详细的配置迁移方案和Log分析技巧。针对常见兼容性问题如对焦速度变慢、低光失效等,给出具体解决方案,并分享性能优化案例与高级调试工具链,帮助开发者快速提升PDAF调试效率。

weixin_29164185的博客 413

轻松掌握java读写锁(ReentrantReadWriteLock)的实现原理

前言前面介绍了java中排它锁,共享锁的底层实现机制,本篇再进一步,学习非常有用的读写锁。鉴于读写锁比其他的锁要复杂,不想堆一大波的文字,本篇会试图图解式说明,把读写锁的机制用另外一种方式阐述。

yanyan19880509的专栏 3万+

基于SHIS凝视型短波红外高光谱相机(900-1700nm)区分不同宝石的差异性和可分性(宝石分选)

SHIS系列凝视型高光谱相机基于液晶可调谐滤波器(LCTF),通过电控LCTF进行连续细分窄波段分光,对每个波段进行高分辨率的二维面阵成像,进行图像处理后,获得完整的高光谱高清图像序列。具有低功耗、小型化、使用方便和易于扩展的优势。其工作波段覆盖400nm至1000nm,能够捕捉宝石在不同波长下的光谱特征,为宝石鉴定提供了新的工具。

wayho的博客 710

读锁有什么用?读为什么要加锁?

读为什么要加锁? 1、有些同学认为读锁没有用,他们的理由是:读操作又不会修改数据,想读就读呗,无论读的是就值还是新值,反正能读到。 2、也有同学认为读锁是为了防止多线程读到的数据不一致。 我认为不是这个原因,只需要问两个问题就知道了,首先问不一致的是什么?然后反问不一致会导致什么问题呢? 有些同学认为不一致就是有些线程读的是旧值,有些读的是新值,所以不一致。但是反问导致什么问题,就不是很好回答了,可能回答说为了保险吧,哈哈哈。 实际上即使加读锁,还是会存在有的线程读旧值,有的线程读新值,甚至非公平

weixin_37990128的博客 4385

携程酒店数据爬取进阶:动态接口破解与反反爬策略实战

本文详细解析了携程酒店数据爬取的进阶技巧,包括动态接口参数破解、反爬虫策略对抗及企业级采集方案实现。重点介绍了eleven参数的生成逻辑、动态Cookie维护方法,以及如何应对携程的请求指纹检测和行为模式识别。通过实战案例,帮助开发者高效获取酒店价格数据,同时遵守行业规范。

eee77的博客 1081

从叶片之舞到数据之眼:净空雷达如何重塑风电安全与效率的边界

净空雷达通过激光或毫米波技术实现风机叶片与塔筒间距离的毫米级实时监测,极大提升了风电场在极端天气下的安全性与运营效率。这项技术不仅预防扫塔事故,还通过数据可视化与智能分析赋能叶片健康管理和发电优化,成为风电数字化运维的核心基础设施。

xk7n92h3p5m的博客 1162

Java并发-AQS及各种Lock锁的原理

什么是AQS AQS是AbustactQueuedSynchronizer的简称,它是一个Java提高的底层同步工具类,用一个int类型的变量表示同步状态,并提供了一系列的CAS操作来管理这个同步状态。AQS的主要作用是为Java中的并发同步组件提供统一的底层支持,例如ReentrantLock,CountdowLatch就是基于AQS实现的,用法是通过继承AQS实现其模版方法,然后将子类作为同...

不瘦十斤不换名字 3万+

实测昇腾310P跑Qwen3有多慢?手把手带你部署vLLM并记录性能数据

本文实测了昇腾310P在vLLM框架下部署Qwen3模型的性能表现,详细记录了2.5 tokens/s的生成速度及其技术瓶颈。通过环境搭建、基准测试和深度分析,揭示了计算资源利用率不足等关键问题,并提供了实用的优化技巧与监控方案,帮助开发者更好地理解和优化昇腾平台上的大模型部署。

weixin_28724319的博客 896

关于正确使用读写锁的思考

使用读写锁可以大幅度提升性能,在读远大于写线程数目时, 本文主要是关于读写锁的一些疑惑 ,主要是实现缓存时,下面这段代码演示了常见的实现缓存的代码:(你可以在很多其他的博客中看到:) 我这里参考了:http://blog.youkuaiyun.com/yangfanend/article/details/7381530 这篇博客中的实现 如下:public class ReadWriteLockCach

scugxl的专栏 1190

Win10下Delphi 10.4.2 (RAD Studio 10.4.2 )安装教程图解

Win10下Delphi 10.4.2 (RAD Studio 10.4.2 )安装和破解教程图解

1万+

Altera Quartus II FPGA固件烧录全攻略:从SOF到JIC的完整流程(附EPCQ128配置技巧)

本文详细介绍了使用Altera Quartus II工具链将FPGA固件从SOF文件转换为JIC文件并烧录到EPCQ128 Flash芯片的完整流程。内容涵盖环境配置、文件转换步骤、EPCQ128专用配置技巧以及常见问题解决方案,帮助工程师实现FPGA固件的flash固化,确保设计可靠运行。

weixin_30275415的博客 206

【并发编程】显式锁和AQS

显式锁 有了synchronized为什么还要Lock? Java程序是靠synchronized关键字实现锁功能的,使用synchronized关键字将会隐式地获取锁,但是它将锁的获取和释放固化了,也就是先获取再释放。 Lock的标准用法/** *类说明:使用Lock的范例 */public class Lock...

猫巳的博客 1056

巡检类机器人电池容量计算方法论(原理+算法+真实案例)

摘要:本文系统阐述了巡检机器人电池容量的计算方法,重点解析了;能量平衡;核心原理和三种主流算法。通过光伏电站履带式巡检机器人的真实案例,详细演示了从工况拆解、功耗采集到容量计算的完整流程。文章指出:室内轻载场景可采用静态平均功耗法,户外常规工况推荐动态负载积分法,而复杂环境需采用融合估算算法。特别强调需考虑温度修正(冬季容量衰减20%)、冗余系数(1.2-1.5)和放电深度(磷酸铁锂DoD取80%)等关键参数。

start_up_go的博客 243

Java并发-显式锁篇【可重入锁+读写锁】

作者:汤圆 个人博客:javalover.cc 前言 在前面并发的开篇,我们介绍过内置锁synchronized; 这节我们再介绍下显式锁Lock 显式锁包括:可重入锁ReentrantLock、读写锁ReadWriteLock 关系如下所示: 简介 显式锁和内置锁最大的区别就是:显式锁需手动获取锁和释放锁,而内置锁不需要 关于显式锁,本节会分别介绍可它的实现类 - 可重入锁,以及它的相关类 - 读写锁 可重入锁,实现了显式锁,意思就是可重入的显式锁(内置锁也是可重入的) 读写锁,将显式锁分为读写

汤圆学Java 499

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

Java并发:互斥锁和读写锁

互斥锁线程在进入同步代码块之前会自动获取锁,并且在退出同步代码块时会自动释放锁,当某个线程请求一个由其他线程持有的锁时,发出请求的线程就会阻塞。互斥锁其实提供了一种原子操作,让所有线程以串行的方式执行同步代码块。可重入性:某个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功(重复获取),这就叫互斥锁的可重入性。“重入”意味着获取锁的操作的粒度是“线程”,而不是调用,也就是说一个线程中可以

jiq•钦's technical Blog 9022

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

Java并发编程(十三):显式锁之ReentrantLock与ReentrantReadWriteLock

本文介绍了 Java 中的显式锁,包括 ReentrantLock 与 ReentrantReadWriteLock。对比了显式锁和 synchronized 的不同,阐述了 ReentrantLock 的特点、使用示例及优势,还介绍了公平锁和非公平锁的区别,最后详细讲解了 ReentrantReadWriteLock 的读写锁机制、使用场景及示例,对多线程同步机制进行了全面阐释。

欧阳方超的专栏 1245

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

显式锁Lock和读写锁ReadWriteLock

一、显式锁Lock 特点:可轮询的、定时的以及可中断的锁获取操作、非快结构的加锁(对应于synchronized的加锁和释放都是在同一块代码块中) public interface Lock {     void lock();     void lockInterruptibly() throws InterruptedException;//可中断锁(在获取锁的时候可以响应中断)     bo...

l1394049664的博客 656

7. Java并发编程的魅力之synchronized隐式锁和Lock显式锁

synchronized隐式锁和Lock显式锁

极客星云-优快云博客 823

【Java并发编程】显式锁:Lock接口

Lock

weixin_44735928的博客 932

Java 并发编程-显式锁

Java 并发编程-显式锁 在 Java5.0 之前,在协调对对象的访问时可以使用的机制只有 synchronized 和 volatile。 Java5.0 增加了一种新的机制:ReentrantLock,ReentrantLock 并不是一种替代的内置加锁的方法, 而是内置加锁机制不适用时,作为一种可选择的高级功能。 1. Lock 与 ReentrantLock 下面给出了 Lock 接口,Lock 接口中定义了一组抽象的加锁操作,与内置加锁机制不同的是,Lock 提供了一种无条件的、可轮询的、定时

liam12138的博客 242

Java并发编程显式锁

显式锁 有了 synchronized 为什么还要 Lock? Java 程序是靠 synchronized 关键字实现锁功能的,使用 synchronized 关键字 将会隐式地获取锁,但是它将锁的获取和释放固化了,也就是先获取再释放。 Synchronized 关键字结合对象的监视器,JVM 为我们提供了一种『内置锁』的语义,这种锁很简便,不需要我们关心加锁和释放锁的过程,我们只需要告...

深入Java世界:探索编程之美与技术深度 346

Java编程拾遗『显式锁』

在之前讲线程同步时,介绍了synchronized的锁的使用及底层原理,也介绍了synchronized锁的一些使用局限,本篇文章来介绍一下Java中提供的另一种线程同步机制——显式锁。Java并发包中的显式锁接口和类位于包java.util.concurrent.locks下,主要接口和类有: 锁接口Lock,主要实现类是ReentrantLock 读写锁接口ReadWriteLock,主要...

卓立的博客 252

线程的显式锁(Lock)·读写锁(ReadWriteLock)·条件阻塞(Condition)

显式锁·读写锁·条件阻塞0 锁的条件1. 显式锁(Lock)1.1 用法场景1.2 Lock与synchronized1.3 显式锁(Lock)的具体实现2. 读写锁(ReadWriteLock)2.1用法场景2.2原理2.3实现代码3. 条件阻塞(Condition)3.1 Condition的优点3.2具体实现 在一些多个线程同时访问一些共享数据,一般都会涉及到线程安全问题。这时候就需要使用...

站在墙头上的博客 942

Java显式锁

synchronized和Lock synchronized Java提供的关键字,属于Java语法层面的互斥,隐式锁,由JVM来实现加锁和释放锁。 优点 代码编写简单 可读性好 缺点 加锁和释放锁由JVM来完成,不够灵活。 获取锁的过程不可中断。 不支持超时,获取不到锁会一直阻塞。 非公平锁,不允许修改。 不支持尝试获取锁的判断。 不支持读写锁,比较僵硬。 Lock Lock属于Java...

程序员小潘 3261

并发编程-显式锁

显式锁 Java 程序是靠synchronized 关键字实现锁功能的,使用synchronized 关键字将会隐式地获取锁,但是它将锁的获取和释放固化了,也就是先获取再释放。 Lock 在finally 块中释放锁,目的是保证在获取到锁之后,最终能够被释放。 ReentrantLock 1. 锁的可重入 简单地讲就是:“同一个线程对于已经获得到的锁,可以多次继续申请到该锁的使用权”。而sync...

Andy_Health的博客 222

JAVA并发编程实战-显式锁

目录思维导图1 Lock和ReentrantLock1.1 可轮询的和可定时的锁1.2 可中断的锁获取操作2 对性能的考量3 公平性4 在内部锁synchronized和ReentrantLock直接进行选择5 读写锁总结参考文献 思维导图 1 Lock和ReentrantLock Lock定义了抽象的锁操作,如下图 Lock提供了无条件的、可中断的、可轮询的和定时的获取锁操作。 Lock的实现与内部锁具有相同的内存可见性语义。 ReentrantLock实现了Lock接口,提供了与synchron

qq_36566262的博客 658
上一篇: Java并发编程(9)-CountDownLatch
下一篇: Java并发编程(11)-使用ReentrantLock与Condition实现生产者-消费者队列
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值