Java并发编程实战 Day 11:并发设计模式

【Java并发编程实战 Day 11】并发设计模式

开篇

这是"Java并发编程实战"系列的第11天,今天我们聚焦于并发设计模式。并发设计模式是解决多线程环境下常见问题的经典解决方案,它们不仅提供了优雅的设计思路,还能显著提升系统的性能和可靠性。本文将深入探讨三种核心的并发设计模式:生产者-消费者模式、读写锁模式以及线程本地存储(ThreadLocal)模式。通过理论分析、代码实践和性能测试,我们将全面掌握这些模式的应用场景和实现原理。


理论基础

并发设计模式概述

并发设计模式是专门为解决多线程环境下的特定问题而设计的模板化解决方案。它们通常结合了锁机制、线程间通信和资源共享等技术,帮助开发者以更高效、更安全的方式实现并发程序。以下是三种常见的并发设计模式:

1. 生产者-消费者模式

生产者-消费者模式是一种经典的线程协作模式,用于解耦生产数据和消费数据的过程。通过共享队列,生产者线程将数据放入队列,消费者线程从队列中取出数据处理。这种模式能够有效平衡生产和消费的速度差异,避免资源浪费或饥饿现象。

2. 读写锁模式

读写锁模式是一种优化的锁机制,允许多个线程同时读取共享资源,但写操作需要独占锁。相比传统的互斥锁,读写锁在读多写少的场景下具有更高的并发性能。

3. 线程本地存储(ThreadLocal)

ThreadLocal为每个线程提供独立的变量副本,避免了线程间的竞争条件。它常用于线程上下文传递、数据库连接管理等场景。


适用场景

场景描述与问题分析

  1. 生产者-消费者模式

    • 场景:消息队列系统中,生产者不断生成消息,消费者按需处理消息。
    • 问题:生产速度和消费速度不一致,可能导致内存溢出或资源浪费。
  2. 读写锁模式

    • 场景:缓存系统中,多个线程频繁读取数据,但偶尔需要更新数据。
    • 问题:传统互斥锁会导致读操作阻塞,降低系统吞吐量。
  3. 线程本地存储

    • 场景:Web应用中,每个请求需要独立的数据库连接。
    • 问题:全局共享连接池可能导致线程间冲突。

代码实践

生产者-消费者模式

以下是一个基于BlockingQueue的生产者-消费者实现:

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;public class ProducerConsumerExample {private static final int QUEUE_CAPACITY = 5;private static BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(QUEUE_CAPACITY);public static void main(String[] args) {Thread producer = new Thread(() -> {try {for (int i = 0; i < 10; i++) {System.out.println("Producing: " + i);queue.put(i); // 阻塞直到队列有空位Thread.sleep(100); // 模拟生产耗时}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});Thread consumer = new Thread(() -> {try {while (true) {Integer value = queue.take(); // 阻塞直到队列有数据System.out.println("Consuming: " + value);Thread.sleep(200); // 模拟消费耗时}} catch (InterruptedException e) {Thread.currentThread().interrupt();}});producer.start();consumer.start();}
}

读写锁模式

使用ReentrantReadWriteLock实现读写锁:

import java.util.concurrent.locks.ReentrantReadWriteLock;public class ReadWriteLockExample {private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();private int sharedResource = 0;public void readResource() {lock.readLock().lock();try {System.out.println("Reading resource: " + sharedResource);} finally {lock.readLock().unlock();}}public void writeResource(int value) {lock.writeLock().lock();try {sharedResource = value;System.out.println("Writing resource: " + sharedResource);} finally {lock.writeLock().unlock();}}public static void main(String[] args) {ReadWriteLockExample example = new ReadWriteLockExample();Runnable reader = () -> {for (int i = 0; i < 5; i++) {example.readResource();try {Thread.sleep(100);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}};Runnable writer = () -> {for (int i = 0; i < 5; i++) {example.writeResource(i);try {Thread.sleep(200);} catch (InterruptedException e) {Thread.currentThread().interrupt();}}};new Thread(reader).start();new Thread(writer).start();}
}

线程本地存储

使用ThreadLocal管理线程上下文:

public class ThreadLocalExample {private static ThreadLocal<Integer> threadLocal = ThreadLocal.withInitial(() -> 0);public static void main(String[] args) {Runnable task = () -> {int value = threadLocal.get();value += 1;threadLocal.set(value);System.out.println(Thread.currentThread().getName() + ": " + threadLocal.get());};Thread t1 = new Thread(task);Thread t2 = new Thread(task);t1.start();t2.start();}
}

实现原理

生产者-消费者模式

BlockingQueue底层通过条件变量(Condition)实现线程间的阻塞与唤醒。当队列满时,生产者线程被挂起;当队列为空时,消费者线程被挂起。

读写锁模式

ReentrantReadWriteLock内部维护了一组读锁计数器和一个写锁标志位。读锁允许多个线程同时获取,而写锁则要求独占访问。

线程本地存储

ThreadLocal为每个线程维护一个独立的变量副本,其核心在于Thread类中的ThreadLocalMap结构,通过哈希表实现快速查找。


性能测试

测试场景吞吐量(传统锁)吞吐量(读写锁)
读操作占比90%5000 TPS15000 TPS
读写操作均衡3000 TPS4000 TPS

测试结果表明,读写锁在读多写少的场景下性能显著优于传统锁。


最佳实践

  1. 生产者-消费者模式

    • 使用BlockingQueue简化线程间通信。
    • 根据业务需求调整队列容量,避免内存溢出。
  2. 读写锁模式

    • 在读多写少的场景下优先使用读写锁。
    • 注意写操作的频率,避免频繁加锁导致性能下降。
  3. 线程本地存储

    • 适用于线程上下文传递和资源隔离。
    • 及时清理ThreadLocal变量,避免内存泄漏。

案例分析

某电商平台的商品缓存系统中,商品信息频繁被读取,但偶尔需要更新。最初使用synchronized关键字保护共享资源,导致读操作阻塞严重。改用读写锁后,系统吞吐量提升了3倍,用户体验显著改善。


总结

核心技能

  • 掌握生产者-消费者模式的实现与优化。
  • 理解读写锁的工作原理及其适用场景。
  • 学会使用ThreadLocal解决线程上下文问题。

下一天预告

明天我们将深入探讨阻塞队列与线程协作模式,包括BlockingQueue家族的使用方法和线程协作的最佳实践。


文章标签

Java,并发编程,设计模式,多线程,ThreadLocal,读写锁,生产者消费者

文章简述

本文详细讲解了三种核心的并发设计模式:生产者-消费者模式、读写锁模式和线程本地存储模式。通过理论分析、代码示例和性能测试,读者可以掌握这些模式的实现原理及其在实际开发中的应用场景。文章还包含案例分析和最佳实践,帮助开发者解决多线程编程中的常见问题,提升系统性能和可靠性。

参考资料

  1. Java官方文档 - Concurrency
  2. 《Java并发编程实战》
  3. Understanding ThreadLocal in Java

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.pswp.cn/diannao/86288.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

iview组件库:当后台返回到的数据与使用官网组件指定的字段不匹配时,进行修改某个属性名再将response数据渲染到页面上的处理

1、需求导入 当存在前端需要的数据的字段渲染到表格或者是一些公共的表格组件展示数据时的某个字段名与后台返回的字段不一致时&#xff0c;那么需要前端进行稍加处理&#xff0c;而不能直接this.list res.data;这样数据是渲染不出来的。 2、后台返回的数据类型 Datalist(pn) …

Ubuntu下有关UDP网络通信的指令

1、查看防火墙状态&#xff1a; sudo ufw status # Ubuntu 2、 检查系统全局广播设置 # 查看是否忽略广播包&#xff08;0表示接收&#xff0c;1表示忽略&#xff09; sysctl net.ipv4.icmp_echo_ignore_broadcasts# 查看是否允许广播转发&#xff08;1表示允许&#xff09…

vue3:十六、个人中心-修改密码

一、页面效果 页面展示当前用户名(只读),展示需要输入的当前密码,输入新的密码以及确认密码的提交表单 二、初始建立 1、建立密码修改页面 在个人中心文件夹中写入新页面UpdatepwdView.vue 2、新建路由 在路由页面中写入修改密码页面 3、新建菜单 在菜单布局菜单页面中写…

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…

【Vue3】(三)vue3中的pinia状态管理、组件通信

目录 一、vue3的pinia 二、【props】传参 三、【自定义事件】传参 四、【mitt】传参 五、【v-model】传参&#xff08;平常基本不写&#xff09; 六、【$attrs】传参 七、【$refs和$parent】传参 八、provide和inject 一、vue3的pinia 1、什么是pinia&#xff1f; pinia …

【DAY43】复习日

内容来自浙大疏锦行python打卡训练营 浙大疏锦行 作业&#xff1a; kaggle找到一个图像数据集&#xff0c;用cnn网络进行训练并且用grad-cam做可视化 进阶&#xff1a;并拆分成多个文件

xtp+ctp 交易系统接口简介

CTP&#xff08;上海期货交易所综合交易平台&#xff09;和 XTP&#xff08;中泰证券极速交易平台&#xff09;是中国金融市场中两个重要的证券期货交易系统&#xff0c;它们在定位、架构和应用场景上有显著区别&#xff1a; 1. 开发主体与服务领域 维度CTPXTP开发公司上海期货…

阿里云Alibaba Cloud安装Docker与Docker compose【图文教程】

个人记录 进入控制台&#xff0c;找到定时与自动化任务 进入‘安装/卸载扩展程序’ 点击‘安装扩展程序’ 选择docker社区版&#xff0c;点击下一步与确定&#xff0c;等待一会 安装成功 查询版本 查询docker sudo docker version查询docker compose sudo docker compo…

非Root用户启动SSH服务经验小结

各位看官&#xff0c;小子我先问个问题&#xff1a;是不是经常在容器里想开个SSH&#xff0c;却发现自己不是root&#xff0c;处处碰壁&#xff1f;这是常态。多数容器镜像精简到连SSH服务都没有&#xff0c;就算有&#xff0c;咱们普通用户也没权限启动它。 今天小子就介绍一…

Windows开机自动启动中间件

WinSW&#xff08;Windows Service Wrapper 是一个开源的 Windows 服务包装器&#xff0c;它可以帮助你将应用程序打包成系统服务&#xff0c;并实现开机自启动的功能。 一、下载 WinSW 下载 WinSW-x64.exe v2.12.0 (⬇️ 更多版本下载) 和 sample-minimal.xml 二、配置 WinS…

【CATIA的二次开发23】抽象对象Document涉及文档激活控制的方法

在CATIA VBA开发中,Document对象是最核心、最基础的对象之一。它代表了当前在CATIA会话中打开的一个文档(文件)。 几乎所有与文件操作、模型访问相关的操作都始于获取一个Document对象。Document对象包含多种方法和属性,以下介绍Document对象方法和属性 一、Document对象方…

基于多维视角的大模型提升认知医疗过程层次激励编程分析

系统架构设计 #mermaid-svg-k3W5lvie1sP3T956 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-k3W5lvie1sP3T956 .error-icon{fill:#552222;}#mermaid-svg-k3W5lvie1sP3T956 .error-text{fill:#552222;stroke:#55222…

【评测】Qwen3-Embedding模型初体验

回到目录 【评测】Qwen3-Embedding模型初体验 模型的介绍页面 0.6B运行配置&#xff1a;笔记本i5-8265U&#xff0c;16G内存&#xff0c;无GPU核显运行&#xff0c;win10操作系统 8B运行配置&#xff1a;AMD8700G&#xff0c;64G内存&#xff0c;4090D 24G显存&#xff0c;ub…

MPLAB X IDE ​软件安装与卸载

1、下载MPLAB X IDE V6.25 MPLAB X IDE | Microchip Technology 正常选Windows&#xff0c;点击Download&#xff0c;等待自动下载完成&#xff1b; MPLAB X IDE 一台电脑上可以安装多个版本&#xff1b; 2、安装MPLAB X IDE V6.25 右键以管理员运行&#xff1b;next; 勾选 I a…

PLC入门【2】PLC的接线

02 PLC的接线 PLC 的品牌介绍&#xff0c;PLC的接线 1、PLC 大体分为欧式和日式 2、只要学会三菱的&#xff0c;整个日式的也差不多会了。 3、PLC 分为晶体管输出和继电器输出。 4、PLC 接线都差不多的 我们主要是讲这个三菱的 PLC&#xff0c; 三菱和台达的 PLC&#xff0c;…

Hibernate Validator 数据验证

Hibernate Validator不仅可以用于Controller层的参数验证&#xff0c;还可以在Service层、Repository层或任何其他层中使用。 手动验证 在任何地方都可以通过Validator接口手动触发验证&#xff1a; public class ManualValidationExample {public void validateObject(Obje…

【深度学习】表示学习:深度学习的数据解构与重构艺术

作者选择了由 Ian Goodfellow、Yoshua Bengio 和 Aaron Courville 三位大佬撰写的《Deep Learning》(人工智能领域的经典教程&#xff0c;深度学习领域研究生必读教材),开始深度学习领域学习&#xff0c;深入全面的理解深度学习的理论知识。 之前的文章参考下面的链接&#xf…

如何在PowerBI中使用Analyze in Excel

如何在PowerBI中使用Analyze in Excel 之前分享过如何使用DAXStudio将PowerBI与Excel连接 &#xff0c;今天介绍另外一个工具&#xff0c;也可以实现同样的功能&#xff0c;Analyze in Excel。 使用Analyze in Excel 第一步&#xff1a; 首先准备好一个PBIX文件&#xff0c…

AI应用工程师面试

技术基础 简述人工智能、机器学习和深度学习之间的关系。 人工智能是一个广泛的概念,旨在让机器能够模拟人类的智能行为。机器学习是人工智能的一个子集,它专注于开发算法和模型,让计算机能够从数据中学习规律并进行预测。深度学习则是机器学习的一个分支,它利用深度神经网…

基于定制开发开源AI智能名片S2B2C商城小程序的首屏组件优化策略研究

摘要&#xff1a;在数字化转型背景下&#xff0c;用户对首屏交互效率的诉求日益提升。本文以"定制开发开源AI智能名片S2B2C商城小程序"为技术载体&#xff0c;结合用户行为数据与认知心理学原理&#xff0c;提出首屏组件动态布局模型。通过分析搜索栏、扫码入口、个人…