JavaSE-多线程(8)- ReadWriteLock

Zookeeper学习:Zookeeper应用场景之分布式锁 1. 分布式锁的介绍 分布式锁是控制分布式系统之间同步访问共享资源的一种方式。如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要通过一些互斥手段来防止彼此之间的干扰,以保证一致性,在这种情况下,就需要使用分布式锁了。 在平时的实际项目开发中,我们往往很少会去在意分布式锁,而是依赖于关系型数据库固有的排他性来实现不同进程之间的互斥。这确实是一种非常简便且被广泛使用的分布式锁实现方式。然而有一个不争的事实是,目前绝大多数大型分布式系统的性能瓶颈都集中在数据库操作上。 阅读详情

JavaSE-多线程(8)- ReadWriteLock

以下例子中多个线程同时对count进行读写,读方法和写方法都等待1秒,并且读写方法都使用了ReentrantLock重入锁,通过CountDownLatch工具类让主线程等待读写线程结束,最后程序输出执行时间为12秒左右

例1

package com.hs.example.base.multithread.day01;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public class ReadWriteTest {
    private volatile int count;
    private Lock lock;

    public ReadWriteTest(Lock lock) {
        this.lock = lock;
    }

    public void accumulate() {
        try {
            lock.lock();
            Thread.sleep(1000);
            count++;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public int getCount() {
        try {
            lock.lock();
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + " : " + this.count);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return this.count;
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(12);
        Lock lock = new ReentrantLock();
        ReadWriteTest readWriteTest = new ReadWriteTest(lock);

        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                readWriteTest.accumulate();
                countDownLatch.countDown();
            }).start();
        }

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                readWriteTest.getCount();
                countDownLatch.countDown();
            }).start();
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("耗时:" + (System.currentTimeMillis() - start));
    }
}

Thread-2 : 2
Thread-3 : 2
Thread-4 : 2
Thread-5 : 2
Thread-6 : 2
Thread-7 : 2
Thread-8 : 2
Thread-9 : 2
Thread-10 : 2
Thread-11 : 2
耗时:12060

例2 是对例1 的改造,从输出结果可见,多线程执行读写时间为 3 秒左右,在此例中,使用 ReentrantReadWriteLock 读写锁,当读取count值时使用 readLock 读锁,写入count数据时使用 writeLock 写锁,由输出结果可知,读取数据的线程几乎在同一时间执行,可见,当读操作较多时,读写锁可提高效率

例2

package com.hs.example.base.multithread.day01;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class ReadWriteTest2 {
    private volatile int count;

    public void accumulate(Lock lock) {
        try {
            lock.lock();
            Thread.sleep(1000);
            count++;
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public  int getCount(Lock lock) {
        try {
            lock.lock();
            Thread.sleep(1000);
            System.out.println(Thread.currentThread().getName() + " : " + this.count);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            lock.unlock();
        }
        return this.count;
    }

    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        CountDownLatch countDownLatch = new CountDownLatch(12);
        ReadWriteLock readWriteLock = new ReentrantReadWriteLock();
        ReadWriteTest2 readWriteTest = new ReadWriteTest2();

        for (int i = 0; i < 2; i++) {
            new Thread(() -> {
                readWriteTest.accumulate(readWriteLock.writeLock());
                countDownLatch.countDown();
            }).start();
        }

        for (int i = 0; i < 10; i++) {
            new Thread(() -> {
                readWriteTest.getCount(readWriteLock.readLock());
                countDownLatch.countDown();
            }).start();
        }

        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("耗时:" + (System.currentTimeMillis() - start));
    }
}
Thread-7 : 2
Thread-5 : 2
Thread-3 : 2
Thread-11 : 2
Thread-9 : 2
Thread-4 : 2
Thread-8 : 2
Thread-10 : 2
Thread-6 : 2
Thread-2 : 2
耗时:3060
【并发编程篇】读锁readLock()和写锁writeLock() 方法返回一个读锁,允许同时获取该锁,以进行并发读取操作。如果当前已有一个写锁或其他线程正在请求写锁,则读锁会被阻塞,直到所有写锁请求完成并释放锁为止。读锁和写锁之间是互斥的。方法返回一个写锁,只允许获取该锁,以进行写入操作。如果当前已有一个读锁或其他线程正在请求读锁,则写锁会被阻塞,直到所有读锁请求完成并释放锁为止。写锁是独占的,同一时间只能有一个线程持有写锁。在使用读写锁时,应该根据具体的业务场景和需求选择适当的锁类型。如果共享资源的读取操作远远超过写入操作,那么使用读写锁可以提高系统的并发性能。 阅读详情

相关推荐

通俗易懂读写锁ReentrantReadWriteLock的使用

ReentrantReadWriteLock不知道大家熟悉吗?其实在实际的项目中用的比较少,反正我所在的项目没有用到过。ReentrantReadWriteLock称为读写锁,它提供一个读锁,支持多个线程共享同一把锁。它也提供了一把写锁,是独占锁,和其他读锁或者写锁互斥,表明只有一个线程能持有锁资源。通过两把锁的协同工作,能够最大化的提高读写的性能,特别是读多写少的场景,而往往大部分的场景都是读多写少的。本文主要讲解ReentrantReadWriteLock的使用和应用场景。

m0_71777195的博客 5929

ReadWriteLock(读写锁)

ReadWriteLock ReadWriteLock也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个资源可以被多个线程同时读,或者被一个线程写,但是不能同时存在读和写线程。 读锁:共享锁 readLock **写锁:**独占锁 writeLock 读写锁 : 一个资源可以被多个读的线程进行访问 ,或者可以被一个写的线程访问, 但是不能同时存在读和写进程 ,读写互斥,读读共享。 读的时候可以多个线程一起读 写的时候只能一个线程写 使用示例: 向map中添加和读取值 p

Student111w的博客 2万+

代号OneNET02 STM32+ESP8266 WIFI系列-第2节-STM32单片机通过ESP8266连接WIFI访问OneNET OTA服务器实现SOTA远程程序升级

第2节-STM32单片机通过ESP8266连接WIFI访问OneNET OTA服务器实现SOTA远程程序升级,这一节主要是实现通过OneNET OTA服务器将需要更新的程序远程下载到STM32单片机,这一节主要是引导程序和应用程序的讲解。

weixin_44862509的博客 1905

排他锁(EXclusive Lock)

排他锁(EXclusive Lock)

Leon_Jinhai_Sun的博客 4158

IBM X3650 M4做raid阵列

步骤1.开机出现此界面,同时按ctrl键和h键,进入IBM X3650 M4配置raid界面。 【注】不知道是不是因为我的服务器长期闲置,按键ctrl键和h键居然无法进入raid配置界面。这时候,我们可以进bios同样可以进入raid配置界面。如果你按ctrl键和h键就可以直接进入raid配置界面,那么请忽略此段,直接看步骤2 开机,按键F1,选中system setting ,接着选中Adapters and UEFI Drivers ...

ani5565的博客 2万+

提升RAG效果:为何 JSON 格式远胜 Markdown?

在构建强大的 RAG (检索增强生成) 系统时,文档解析是至关重要的第一步。它直接影响着后续的检索效率和生成质量。在众多文档格式中,JSON (JavaScript Object Notation) 格式正逐渐展现出其相对于传统 Markdown 格式的巨大优势。本文将深入探讨 JSON 在 RAG 系统文档解析中的卓越之处,并结合具体案例,让你理解为何 JSON 才是构建下一代智能应用的更优选择。RAG 系统的核心目标是让模型能够利用外部知识库,生成更精准、更贴合实际的答案。

simoncool23的博客 2718

JavaSE进阶知识学习----多线程JUC高级知识-4

9.ReadWriteLock读写锁 说明:写写/读写需要‘互斥’,读读不需要‘互斥’。不能一存在线程问题就加锁,读就不需要锁,所以才有了读写分离的读写锁ReadWriteLock。 是一个接口,位于java.util.concurrent.locks包下。有两个方法 Lock readLock() 返回用于读取操作的锁。 Lock writeLock() 返回用于写入操作

疾风知劲草,智者必怀仁 348

UE5网络模块实战:属性复制、RPC与联机开发踩坑指南

多人联机开发中,网络同步是核心难题。UE5网络模块以服务器权威为基础,通过Actor复制、RPC和所有权机制实现多端状态一致。理解属性复制与OnRep回调、区分Server/Client/Multicast RPC的适用场景,是构建稳定联机架构的关键。本文结合数字孪生与多端协作场景,探讨如何将渲染与逻辑分离,并针对打包后网络失效、端口防火墙、崩溃排查等工程实践问题给出解决方案。通过蓝图接口解耦表现层,利用C++创建StaticMesh组件实现服务器逻辑与客户端表现分离,同时注意专用服务器不加载渲染依赖(如D

weixin_29010003的博客 273

初级必备:Java版本区别与了解_JavaSE_多线程2

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_34413065的博客 149

SAP资产按每天折旧功能介绍

注意:此处在计算百分比时将30天作为剩余使用寿命,因为SAPS/4HANA中的计算是通过考虑购置第一年的折旧总天数来进行的。这是因为我在计算总使用寿命时只使用了365天,如果剩余使用寿命大于1年,SAPS/4HANA会将闰年规范化为365天。此功能仅对确定使用寿命或剩余寿命百分比的折旧键有用,如果需要,这种折旧到日的解决方案可以应用于需要每天计算折旧的跨行业(任何国家/行业)。注意:这里在计算百分比时考虑了2天,因为364天已经过期,但目前我们到达2024年,使用寿命为366天。它只会在下一年生效。

yanzibing99的博客 1562

DNF服务器搭建服务端架设教程

第三步:打开winscp,上传Script.pvf(版本)、publickey.pem(密钥)、df_game_r(等级补丁)到home/neople/game目录下。第四步:打开putty输入./stop,./stop(两次,如果是首次架设不用./stop),./run,运行刚才上传的三个游戏文件。③是本地配置登录器的配置文件,自动生成,可以删除,但是还是会根据你生成的登录器生成这个文件,类似日志。⑤密钥中所上传的三个文件其中之一,重中之重,上传到服务器的密钥必须和登录器中的密钥为一个。

V13807970340的博客 6263

javaSE 并发编程基础知识

Synchronize Synchronize是java提供的一种原子性内置锁,也成排他锁、独战锁、互斥锁。进入Synchronize块的语义就是把Synchronize块使用到的变量从工作内存中清除,直接从主存中获取,释放锁就把变量直接写入主存中。 Volatile Volatile关键保证一个变量的更新时对其他线程马上可见,读取写入变量时都是直接到主存中。但是volatile只能保证内存...

qq_37266528的博客 606

NL2SQL进阶系列(3):Data-Copilot、Chat2DB、Vanna Text2SQL优化框架开源应用实践详解[Text2SQL]

NL2SQL进阶系列(3):Data-Copilot、Chat2DB、Vanna Text2SQL优化框架开源应用实践详解[Text2SQL]

丨汀、的博客 5421

JAVA中三种锁简要介绍

锁是多线程并发执行下,通过保证单位时间内只有单个线程对共享资源进行修改,从而保证程序能够正确执行。在Java语言中目前有这样三种锁。 synchronized ReadWriteLock StampedLock(java8) synchronized 实现 Synchronized的语义底层是通过一个monitor的对象来完成,指令monitorenter和monitorexit标记线程获得...

weixin_35833012的博客 810

使用verilog实现基于FPGA的TDC设计

verilog实现TDC 高精度时间数字转换器概述(TDC) 简介: TDC被用于测量时间间隔,应用在物理研究、飞行时间测量领域等。 本设计使用verilog实现并在xilinx和altera的FPGA上均可实现! 设计中使用到下述几个模块,包括FIFO,COUNT等,在xilinx下也使用到了一些原语等。下面有实现的代码和仿真截图等。 顶层模块设计如下: module top( input wire start, input wire stop, input wire clk, output wire T

QQ_778132974的博客 6254

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

AQS的源码分析

AQS: java中的AbstractQuenedSynchronizer抽象的队列式同步器 AQS的两种资源共享方式: 1.Exclusive:独占,只有一个线程能执行,如ReentrantLock 2.Share:共享,多个线程可以同时执行,如Semaphore、CountDownLatch、ReadWriteLock,CyclicBarrier等 AQS原理: AQS维...

qq_20004115的博客 194

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

Java 核心编程之并发简介

1、谈谈Java中的并发 自从java创建以来就已经支持并发的理念,如线程和锁。这篇指南主要是为帮助java多线程开发人员理解并发的核心概念以及如何应用这些理念。本文的主题是关于具有java语言风格的Thread、synchronized、volatile,以及J2SE5中新增的概念,如锁(Lock)、原子性(Atomics)、并发集合类、线程协作摘要、Executors。开发者通过这些基础的接

纸上得来终觉浅,绝知此事要躬行 1380

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

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

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

什么是排他锁和共享锁?区别是什么?

如果不同的系统或是同一个系统的不同主机之间共享了一个或一组资源,那么访问这些资源的时候,往往需要通过一些互斥手段来防止彼此之间的干扰,以保证一致性,在这种情况下,就需要使用分布式锁了。从上面讲解的排他锁的基本概念中,我们可以看到,排他锁的核心是如何保证当前有且仅有一个事务获得锁,并且锁被释放后,所有正在等待获取锁的事务都能够被通知到。共享锁和排他锁最根本的区别在于,加上排他锁后,数据对象只对一个事务可见,而加上共享锁后,数据对所有事务都可见。(2)确定自己的节点序号在所有子节点中的顺序。

zy1992As的博客 1594

读写锁精讲:Java中使用ReadWriteLock提升性能的终极指南

在并发编程中,ReadWriteLock是一个锁,它允许多个线程同时读共享数据,而写操作则是互斥的。这意味着如果没有线程正在对数据进行写入,那么多个线程可以同时进行读取操作,从而提高程序的性能和吞吐量。

逆流的小鱼 3049

MySQL排它锁

记录锁、间隙锁、后码锁,都属于排它锁;记录锁就是锁住一行记录;间隙锁只有在事务隔离级别 RR 中才会产生;唯一索引只有锁住多条记录或者一条不存在的记录的时候,才会产生间隙锁,指定给某条存在的记录加锁的时候,只会加记录锁,不会产生间隙锁;普通索引不管是锁住单条,还是多条记录,都会产生间隙锁;间隙锁会封锁该条记录相邻两个键之间的空白区域,防止其它事务在这个区域内插入、修改、删除数据,这是为了防止出现 幻读 现象;普通索引的间隙,优先以普通索引排序,然后再根据主键索引排序;

2301_78102191的博客 1957

读写锁ReadWriteLock

在jdk帮助文档中是这么说的:A ReadWriteLock维护一对关联的locks,一个用于只读操作,一个用于写操作。read lock可以由多个阅读器同时进行,只要没有作者 write lock 是独家的 意思就是读操作可以被多个线程同时读,写操作只能由一个线程去写 ReadWriteLock同Lock一样也是一个接口,提供了readLock和writeLock两种锁的操作机制,一个是只读的锁,一个是写锁。ReentranReadWriteLock是其...

欢迎一起学习交流 2291

排他锁理解,MySQL实践

排他锁又称为写锁,简称X锁,顾名思义,排他锁就是不能与其他锁并存,如一个事务获取了一个数据行的排他锁,其他事务就不能再获取该行的其他锁,包括共享锁和排他锁,但是获取排他锁的事务是可以对数据就行读取和修改。可以看出在事务一开启了排他锁以后,其他事务(事务二)仍然可以进行读操作,并产生了幻读的结果(事务一修改张三的余额为5000,事务二读取的张三的余额却为7000)。可以看到在事务一开启排他锁的期间,事务二无法进行修改操作,等待20多秒事务一提交后才执行了事务二。事务二对张三的余额进行修改操作。

FENGBOKE的博客 1385

ReadWriteLock(读写锁)的特性及使用

在实际应用中,有种普遍的并发场景:那就是读多写少;这种情况下如果使用互斥锁实现的话效率却不尽人意,一般来说读操作并不对数据的完整性造成破坏,这种互斥等待显然是不合理的;这时候就可以用到我们今天所说的主角:ReadWriteLock,接下来就让我们一步步揭开它神秘的面纱...

mlwsmqq的博客 1241

Java通俗易懂30天 第19天:多线程(下)

文章目录 文章目录文章目录第8章 多线程线程的生命周期线程的同步同步代码块处理实现Runnable的线程安全问题同步代码块处理继承Thread类的线程安全问题同步方法处理实现Runnable的线程安全问题同步方法处理继承Thread类的线程安全问题线程安全的单例模式之懒汉式死锁的问题Lock锁方式解决线程安全问题线程的通信sleep()和wait()的异同经典例题:生产者/消费者问题JDK5.0新增线程创建方式创建多线程的方式三:实现Callable接口使用线程池的好处创建多线程的方式四:使用线程池 ..

程序员小刘 1651

一文搞懂 mysql 中的共享锁、排他锁、悲观锁、乐观锁及使用场景

想要学好 mysql 数据库,锁机制的理解才是打开通往更深层次大门的钥匙

国内某知名游戏公司小菜鸡工程师 8501

并发编程系列 - ReadWriteLock

写缓存则需要用到写锁,写锁的使用和读锁是类似的。如果源头数据量非常大,那么就需要按需加载了,按需加载也叫懒加载,指的是只有当应用查询缓存,并且数据不在缓存里的时候,才触发加载源头相关数据进缓存的操作。需要注意的是,如果缓存中没有缓存目标对象,那么就需要从数据库中加载,然后写入缓存,写缓存需要用到写锁,所以在代码中的⑤处,我们调用了。另外,还需要注意的是,在获取写锁之后,我们并没有直接去查询数据库,而是在代码⑥⑦处,重新验证了一次缓存中是否存在,再次验证如果还是不存在,我们才去查询数据库并更新本地缓存。

795
上一篇: JavaSE-多线程(6)- CountDownLatch
下一篇: JavaSE-多线程(9)- Semaphore
sql2008help
博客等级 码龄11年 80粉丝 145原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值