并发编程之重入锁和读写锁

并发编程系列之重入锁VS读写锁 前言 上节我们介绍了Java中的锁基础篇,也算是对锁有了个基本的认识,对锁底层的一些原理有所掌握,那么今天我们就来看看2个最常见的锁的实例应用,重入锁和读写锁,这是今天旅途最美的两大景点,是不是有点迫不及待了,OK,那就让我们一起开启今天的并发之旅吧,祝您今天的旅途愉快。 景点一:重入锁 什么是重入锁? 重入锁ReentrantLock指的是支持重进入的锁,表示该锁能够支持同一个线程对资源的重复加锁,也就是说当线程对某个资源获取锁之后,该线程继续获取该资源的锁时不会被阻塞; synchron. 阅读详情

Java多线程中,除了sychronized关键字实现多线程之间同步互斥操作,其实还有另外一种高效的机制去完成“同步互斥”操作。即Lock对象,比synchronized关键字更为强大功能,并且有嗅探锁定,多路分支等功能。

重入锁

分为公平锁和非公平锁,默认非公平锁

public ReentrantLock() {
    sync = new NonfairSync();
}

public ReentrantLock(boolean fair) {
    sync = fair ? new FairSync() : new NonfairSync();
}
private Lock lock = new ReentrantLock();
 public void method1(){
    try {
         //加锁
        lock.lock();
        System.out.println("当前线程:" + Thread.currentThread().getName() + "进入method1..");
        Thread.sleep(1000);
        System.out.println("当前线程:" + Thread.currentThread().getName() + "退出method1..");
    } catch (InterruptedException e) {
        e.printStackTrace();
    } finally {
        //一定要释放锁,否则其他线程拥有无法获取
        lock.unlock();
    }
}

以前使用synchronized 关键字进行多线程协同工作时,需要使用Object的wait()阻塞、释放锁,notify()唤醒、不释放锁等进行配合使用。

使用Lock时可以使用新的等待/通知类,Condition一定是针对某一把固定的锁,也就是说,只有在有锁的基础上才会产生Condition。

public class UseCondition {

    private Lock lock = new ReentrantLock();
    private Condition condition = lock.newCondition();

    public void method1(){
        try {
            lock.lock();
            System.out.println("当前线程:" + Thread.currentThread().getName() + "进入等待状态..");
            Thread.sleep(3000);
            System.out.println("当前线程:" + Thread.currentThread().getName() + "释放锁..");
            // 释放锁,类似于Object.wait(),阻塞于此
            condition.await();
            System.out.println("当前线程:" + Thread.currentThread().getName() +"继续执行...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public void method2(){
        try {
            lock.lock();
            System.out.println("当前线程:" + Thread.currentThread().getName() + "进入..");
            Thread.sleep(3000);
            System.out.println("当前线程:" + Thread.currentThread().getName() + "发出唤醒..");
            // 不释放锁类,似于Object.notify()
            condition.signal();
            System.out.println("当前线程:" + Thread.currentThread().getName() + "没有释放锁");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public static void main(String[] args) {

        final UseCondition uc = new UseCondition();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                uc.method1();
            }
        }, "t1");

        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                uc.method2();
            }
        }, "t2");

        t1.start();
        t2.start();
    }
}

结果:
这里写图片描述

读写锁

核心思想实现读写分离,高并发下特别适合读多写少的场景。

之前的synchronized关键字和ReentrantLock同一时间只能有一个线程进行访问被锁定的代码,读写锁的机制则不是,本质上分为两把锁,读锁和写锁,在读锁情况下,多个线程可以并发访问资源,只有当是写锁时,只能一个一个的顺序执行。

口诀:读读共享,写写互斥,读写互斥。

public class UseReentrantReadWriteLock {

    private ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
    private ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock();
    private ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock();

    public void read() {
        try {
            readLock.lock();
            System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");
            Thread.sleep(3000);
            System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            readLock.unlock();
        }
    }

    public void write() {
        try {
            writeLock.lock();
            System.out.println("当前线程:" + Thread.currentThread().getName() + "进入...");
            Thread.sleep(3000);
            System.out.println("当前线程:" + Thread.currentThread().getName() + "退出...");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            writeLock.unlock();
        }
    }

    public static void main(String[] args) {

        final UseReentrantReadWriteLock urrw = new UseReentrantReadWriteLock();

        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                urrw.read();
            }
        }, "t1");
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                urrw.read();
            }
        }, "t2");
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                urrw.write();
            }
        }, "t3");
        Thread t4 = new Thread(new Runnable() {
            @Override
            public void run() {
                urrw.write();
            }
        }, "t4");

        t1.start(); // R
        t2.start(); // R

        //      t1.start(); // R
        //      t3.start(); // W

        t3.start(); // W
        t4.start(); // W
    }
}

结果:
这里写图片描述

JavaScript实现读写锁(附完整源码) 阅读详情

相关推荐

读写锁实现例子

读写锁实现例子

读写锁的实现

读写锁主要用来解决读-读能共存,读-写不能共存,写-写不能共存的情况,它的使用场景主要是读写分离,比如自己实现一个缓存,在刷新缓存的时候就需要用到读写锁。下面撸上一段代码,简单实现以下。 /** * @author Administrator * @date 2019/3/3 */ public class Cache { static Map<String,String&...

FutureFlyme的博客 653

SpringBoot使用Redisson实现分布式锁(秒杀系统)

主要为大家详细介绍了SpringBoot使用Redisson实现分布式锁,秒杀系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

JS与多线程

http://www.renfed.com/2017/05/21/js-threads/?utm_source=tuicool&utm_medium=referral 多线程对前端开发人员来说既熟悉又陌生,一方面前端几乎很少写多线程,另一方面多线程又经常会碰到,如你买个电脑它会标明它是四核八线程、四核四线程之类的,它是多核多线程的。什么叫做多核呢?四核四线程和八线程又有什么区别?

java、c++、机器学习方向King 1327

从零到一:RF-DETR如何通过神经架构搜索重塑实时目标检测的边界

RF-DETR通过创新的权重共享神经架构搜索(NAS)机制,重新定义了实时目标检测的技术边界。这项技术在COCO等基准测试中表现卓越,成为首个AP超过60的实时检测器,同时保持跨领域稳定性和高效推理速度。RF-DETR的动态架构调整能力使其能够适应从嵌入式设备到云端服务器的各种硬件环境,为工业质检、自动驾驶等场景提供灵活解决方案。

weixin_29061531的博客 468

【Audio driver】深入解析mixer_paths.xml中的音频通路配置

本文深入解析了Android音频驱动开发中的核心配置文件mixer_paths.xml。文章以高通平台为例,详细阐述了音频通路(FE、BE、DSP、Device)的概念与连接逻辑,并通过实战案例拆解了扬声器与麦克风通路的配置方法、关键控件作用及调试技巧,是理解与定制Android音频系统的实用指南。

ik6789012的博客 357

多线程(五)可重入锁、读写锁

ReentrantLock、ReentrantReadWriteLock

HK的博客 3418

1. 基于STM32的1.28寸圆形IPS屏(GC9A01)驱动移植实战:软件SPI与硬件SPI双方案详解

本文详细介绍了如何在STM32平台上为1.28寸圆形IPS屏(GC9A01驱动芯片)移植驱动程序,涵盖软件SPI与硬件SPI两种实现方案。内容从引脚定义、工程搭建、GPIO配置到SPI外设初始化逐步详解,并提供了完整的测试代码,帮助开发者根据项目需求(灵活性或性能)选择合适的通信方式,快速点亮屏幕并集成到智能手表等嵌入式项目中。

weixin_42300144的博客 203

[并发进阶]——读写锁 原理

通过图解流程以及阅读源码的方式带你深入理解读写锁,让你真正理解其原理

热爱编程的机械生的救赎 1952

OAI数据集申请与实战:从权限获取到医学影像分析应用

本文详细介绍了OAI数据集的申请流程与医学影像分析实战应用。从NDA账户注册、数据下载技巧到骨盆X光关键点检测的完整实现,帮助医学研究者高效利用这一权威骨关节炎数据集。特别分享使用Pei Y标注数据训练U-Net模型的经验,包括预处理、注意力机制优化等实用技巧。

weixin_30275415的博客 478

【Python音频处理】syncstart 计算媒体文件同步时间偏移

syncstart是一个强大的工具,它简化了多媒体文件的音视频同步过程,特别适用于多设备录制的媒体内容。在使用命令行工具时,可以根据实际需求灵活调整参数,如归一化、降噪、低通滤波等,以提高同步的精度和效率。通过本文介绍的基本操作和应用示例,可以快速掌握syncstart的使用方法,并将其应用到日常的音视频处理工作中。

Mr数据杨 814

Java并发编程的艺术(12)重入锁和读写锁

重入锁 重入锁ReentrantLock,表示该锁能够支持一个线程对资源的重复加锁。支持获取锁时的公平和非公平性选择。 synchronized关键字隐式的支持重进入,比如一个synchronized修饰的递归方法,在方法执行时,执行线程在获取了锁之后仍能连续多次地获得该锁。 ReentrantLock虽然没能像synchronized关键字一样支持隐式的重进入,但是在调用lock()方 法时,已...

qq_45366515的博客 193

PyTorch深度学习实战(41)——循环神经网络与长短期记忆网络

循环神经网络 (Recurrent Neural Network, RNN) 通过将前一个时间步的隐藏状态作为当前时间步的输入,实现对序列数据的建模,由于循环连接的存在,RNN 能够捕获时间依赖关系,然而,RNN 在处理长期依赖性问题时会遇到困难。为了解决这个问题,提出了 LSTM,通过引入门控机制改进 RNN 来有效地处理长期依赖关系。在本节中,了解了 LSTM 和 RNN 的基本原理,并介绍了如何在 PyTorch 中实现 LSTM。

盼小辉丶的博客 1万+

并发编程(四):Java中的锁 重入锁(ReentrantLock)和 读写锁(ReentrantReadWriteLock)

1.重入锁(ReentrantLock):在需要进行同步的代码部分上加上锁定,但不要忘记最后一定要释放锁,不然会造成锁永远无法释放,其他线程永远无法进入。直接上代码: import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import java.util.concur...

ssaiwey的博客 189

【优化求解】基于matlab粒子群算法PSO确定最佳开关角对称级联多层逆变器【含Matlab源码 13080期】

粒子群算法PSO确定最佳开关角对称级联多层逆变器 完整代码,包运行;可提供运行操作视频!适合小白!

订阅付费专栏Matlab(奶茶价版),可赠送奶茶价版付费专栏指定代码1份; 97

RH850系列芯片深度剖析 1.5-链接(ld)文件解析

基础编译过程分为四个阶段:预处理(Preprocessing)、编译(Compilation)、汇编(Assembly)、链接(Linking)。执行这四个阶段的程序(预处理器、编译器、汇编器、和链接器)一起构成了编译系统。CONSTANTS接下来的内存空间定义部分会使用这些常量来定义内存空间的范围,理论上来说不定义常量也没有影响,直接用魔鬼数字代替,定义常量的主要目的就是方便理解以及方便修改;从示例中可以看出,常量的值可以为16进制或者10十进制,而且10进制支持数量级单位(k级,M级);

本博客专注于嵌入式软件领域技术分享。 1427

Java并发编程系列---可重入锁和读写锁的实现原理、源码分析

一、重入锁 1.1 什么是重入锁 重入锁ReentrantLock,就是支持重进入的锁,它表示该锁能够支持一个线程对资源的重复加锁。除此之外,该锁的还支持获取锁时的公平和非公平性选择。 1.2 重入锁有什么用 例子:之前AQS的一个自己实现的锁 package com.example.demo.thread; import java.util.concurrent.TimeUnit; impor...

逆流而上的博客 1200

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Java并发编程十 重入锁ReentrantLock 读写锁ReentrantReadWriteLock

Java并发编程十 重入锁ReentrantLock 读写锁ReentrantReadWriteLock Java的concurrent并发包提供了一套与Synchronized关键字相同功能Lock,还有与wait()/notify()相同功能的Condition。 Lock的功能比传统的Synchronized更加灵活。它具有嗅探锁定和多路分支等功能(一个lock对象可以创建多个Condi...

刘越洋子 357

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【JAVA并发编程系列】并发 -- 锁

【JAVA并发编程系列】锁 【1】Lock 接口 Lock 接口 提供了与 synchronized 关键字类似的同步功能; 在使用时需要显示地获取和释放锁; 缺少了隐式获取与释放锁的便捷性; 拥有获取与释放锁的可操作性、可中断获取锁以及超时获取锁等同步特性; Lock 接口源码分析 【2】队列同步器 队列同步器AbstractQueuedSynchronizer:用于...

CopperSun 技术博客 380

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Java并发编程(二)并发控制

Java并发编程并发一、锁1. Lock接口1)Lock接口简介2)Lock接口的特性3)Lock接口的API4)Lock接口的常用实现重入锁4. LockSupport工具5. Condition接口 并发 一、锁     锁是用来控制多个线程访问共享资源的方式,一般来说,一个锁能够防止多个线程同时访问共享资源(但是有些所可以允许多个线程并发的访问共享资源...

qq_35017434的博客 894

并发编程之Lock及其实现类

1

博客 1024

java并发-锁-ReentrantLock(重入锁)和ReentrantReadWriteLock(读写锁)

同步控制是并发程序必不可少的重要手段,synchronized关键字就是一种简单的控制方式,除此之外,JDK内部并发包中也也提供了Lock接口,该接口中提供了lock()方法和unLock()方法对显式加锁和显式释放锁操作进行支持。 ReentrantLock(重入锁) 重入锁可以完全替代synchronized关键字,在jdk5早期版本中重入锁的性能远远好于synchron...

weixin_30662539的博客 160

并发编程中关于锁的思考

Table of Contents 一 Lock接口 二 AQS队列同步器 2.1 锁是面向使用者的 2.2 同步器面向的是锁的实现者 2.3同步队列 三 ReentrantLock重入锁 3.1实现重进入 3.2公平与非公平获取锁的区别 四ReentrantReadWriteLock读写锁 4.1 读写确定状态 4.2写锁的获取与释放 4.3 读锁的获取与释放 ...

华绪、charles的博客 685

java并发编程的艺术笔记第五章——java中的锁

1、Lock接口 锁是用来控制多个线程访问共享资源的方式,一般来说锁能够防止多个线程同时访问共享资源(有的锁可以允许多个线程访问共享资源,比如说读写锁),在Lock接口出现之前,java程序是靠synchronized关键字实现锁功能的,但是在JKD1.5之后并发包中新增了Lock接口及其实现...

chuchuhui6206的博客 132

Java并发编程中的锁机制详解

Java并发编程中的锁机制详解 大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿! 在Java并发编程中,锁机制是保证线程安全的重要手段。锁的作用是确保同一时刻只有一个线程能够访问被锁保护的资源,从而避免数据不一致和并发冲突。本文将详细介绍Java并发编程中的锁机制,包括内置锁、重入锁、读写锁等...

weixin_28936865的博客 198

JUC并发包之 Lock详解

java.util.concurrent,并发编程常用的工具类:包含了线程池、阻塞队列、计时器、同步器、并发集合等 作者:Dong Lea。 Lock Lock 本质上是一个接口,它定义了释放锁和获得锁的抽象方法,定义成接口就意 味着它定义了锁的一个标准规范,也同时意味着锁的不同实现。 Lock 有很多的锁的实现,但是直观的实现是 ReentrantLock 重入锁。 1.ReentrantLock: 表示重入锁,表示支持重新进入的锁,它是唯一一个实现了 Lock 接口的类。重入锁指的是线程在获得锁之后,再

pengli 425
上一篇: 多线程之CountDownLatch和CyclicBarrier
下一篇: Disruptor中遇到的坑
章 鱼
博客等级 码龄10年 203粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值