并发编程之读写锁ReadWriteLock的详细解析(带小案例)

本文涉及的产品
云解析 DNS,旗舰版 1个月
云解析DNS,个人版 1个月
全局流量管理 GTM,标准版 1个月
简介: 并发编程之读写锁ReadWriteLock的详细解析(带小案例)

读写锁ReadWriteLock

lock锁,只允许一个进程进行读/写

使用ReadWriteLock读写锁,可以实现控制:

  1. 多个线程同时读
  2. 同一时间只允许一个线程写

下面的demo展示的是,当多个线程要进行同时写操作时,没有加锁的情况,会导致多个线程并发写:

运行结果:

代码:

/**
 * @author zkw
 * @Description 读写锁
 */
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyMap map = new MyMap();
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                try {
                    map.put(Thread.currentThread().getName(),"");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },i+"").start();
        }
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                try {
                    map.get(Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },i+"").start();
        }
    }
}
class MyMap{
    private HashMap<String,String> map = new HashMap<>();
    public void put(String key,String value) throws InterruptedException {
        System.out.println(Thread.currentThread().getName()+"开始写入");
        TimeUnit.SECONDS.sleep(1);
        map.put(key, value);
        System.out.println(Thread.currentThread().getName()+"写入完成");
    }
    public String get(String key) throws InterruptedException {
        System.out.println(Thread.currentThread().getName()+"开始读取");
        TimeUnit.SECONDS.sleep(1);
        String s = map.get(key);
        System.out.println(Thread.currentThread().getName()+"读取完成");
        return s;
    }
}

下面使用ReadWriteLock锁对上面的demo进行优化,禁止多个线程同时读的情况,并允许多个线程同时写:

运行结果:

代码:

/**
 * @author zkw
 * @Description 读写锁
 */
public class ReadWriteLockDemo {
    public static void main(String[] args) {
        MyMap map = new MyMap();
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                try {
                    map.put(Thread.currentThread().getName(),"");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },i+"").start();
        }
        for (int i = 0; i < 6; i++) {
            new Thread(()->{
                try {
                    map.get(Thread.currentThread().getName());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            },i+"").start();
        }
    }
}
class MyMap{
    private HashMap<String,String> map = new HashMap<>();
    ReadWriteLock readWriteLock = new ReentrantReadWriteLock();  //创建读写锁
    public void put(String key,String value) throws InterruptedException {
        readWriteLock.writeLock().lock(); //写锁
        System.out.println(Thread.currentThread().getName()+"开始写入");
        TimeUnit.SECONDS.sleep(1);
        map.put(key, value);
        System.out.println(Thread.currentThread().getName()+"写入完成");
        readWriteLock.writeLock().unlock();
    }
    public String get(String key) throws InterruptedException {
        readWriteLock.readLock().lock();  //读锁
        System.out.println(Thread.currentThread().getName()+"开始读取");
        TimeUnit.SECONDS.sleep(1);
        String s = map.get(key);
        System.out.println(Thread.currentThread().getName()+"读取完成");
        readWriteLock.readLock().unlock();
        return s;
    }
}


相关文章
|
28天前
|
并行计算 算法 Java
探索Java并发编程:Fork/Join框架的深度解析
【5月更文挑战第29天】在多核处理器普及的时代,有效利用并发编程以提升程序性能已经成为开发者必须面对的挑战。Java语言提供的Fork/Join框架是一个强大的工具,它旨在利用多线程执行分而治之的任务。本文将通过深入分析Fork/Join框架的工作原理、关键特性以及与传统线程池技术的差异,帮助开发者更好地掌握这一高效处理并发任务的技术手段。
|
1天前
|
Java 程序员 调度
Java并发编程之Executor框架深度解析
【6月更文挑战第24天】在Java的并发编程领域,Executor框架是处理多线程任务的核心。本文将深入探讨Executor框架的设计哲学、核心组件以及如何高效利用这一框架来提升程序的性能和响应性。我们将通过实例演示如何正确配置和使用Executor,并讨论常见的陷阱与最佳实践。
|
3天前
|
数据采集 前端开发 JavaScript
python语言通过简单爬虫实例了解文本解析与读写
python|通过一个简单爬虫实例简单了解文本解析与读写
|
1月前
|
Java 开发者
探索Java并发编程:Fork/Join框架的深度解析
【5月更文挑战第25天】在多核处理器日益普及的今天,并发编程成为了提升应用性能的关键。Java语言提供了多种并发工具,其中Fork/Join框架是一个高效且强大的工具,用于处理分而治之的任务。本文将深入探讨Fork/Join框架的原理、使用及其在实际应用中的优化策略,旨在帮助开发者更好地利用这一框架以解决复杂的并发问题。
|
29天前
|
Python
深入解析Python中的并发编程技术
深入解析Python中的并发编程技术
101 1
|
12天前
|
搜索推荐 Java 程序员
【案例解析】从菜鸟到高手,如何优雅地使用Java条件语句?
【6月更文挑战第14天】本文介绍了Java编程中条件语句的重要性,特别是if-else和switch的使用。通过四个案例,展示了如何优雅地运用这些语句:案例一演示了基础if-else用于用户登录响应;案例二利用switch处理枚举类型,如订单状态;案例三展示了条件语句的嵌套与组合,用于游戏评分系统;案例四探讨了代码优化与重构,减少冗长的if-else结构。文章强调,掌握条件语句能提升编码效率和代码质量,鼓励开发者不断实践以写出高效优雅的代码。
|
1月前
|
数据采集 数据可视化 数据挖掘
利用 DataFrame 进行数据分析:实战案例解析
【5月更文挑战第19天】DataFrame是数据分析利器,本文通过一个销售数据案例展示其使用:读取数据创建DataFrame,计算产品总销量,分析月销售趋势,找出最畅销产品,并进行数据可视化。此外,还提及数据清洗和异常处理。DataFrame为数据处理、分组计算和可视化提供便利,助力高效数据分析。
54 3
|
1月前
|
开发框架 搜索推荐 安全
【Uniapp 专栏】基于 Uniapp 的电商应用开发案例解析
【5月更文挑战第12天】使用Uniapp跨平台框架开发电商应用,结合丰富的组件和API,实现首页、商品详情、购物车及订单等关键功能。注重界面设计和用户体验,处理商品逻辑、订单管理和支付接口集成。同时,适应多平台特性,加入个性化推荐、商品直播和社交分享等特色功能,以降低成本、提升竞争力,打造高效购物体验。此案例展示了Uniapp在电商领域的潜力和优势。
|
28天前
|
安全 Java 调度
Java并发编程:线程池深入解析
【5月更文挑战第29天】本文将详细探讨Java中的线程池技术,包括其基本原理、使用方法以及在实际开发中的应用。我们将通过实例代码和性能分析,深入理解线程池的优势和潜在问题,为高效、安全的并发编程提供指导。
|
5天前
|
机器学习/深度学习 缓存 算法
netty源码解解析(4.0)-25 ByteBuf内存池:PoolArena-PoolChunk
netty源码解解析(4.0)-25 ByteBuf内存池:PoolArena-PoolChunk

推荐镜像

更多