咱就是来聊聊并发编程的三大核心问题。

即时通讯开发如何设计一个百万级的消息推送 先简单介绍下本次要分享的主题,由于我最近做的是物联网相关的开发工作,其中就不免会遇到和设备的数据通信(交互)。这里的核心代码和 「造个轮子」——cicada(轻量级 Web 框架)是一致的(另外,即时通讯网的MobileIMSDK工程也使用了同样的API解偶设计思路)。常见和简单的是 HTTP 协议,但我们的需求中有一项需要是双全工的交互方式,同时 HTTP 更多的是服务于浏览器。百万连接其实只是一个形容词,更多的是想表达如何来实现一个分布式的方案,可以灵活的水平拓展从而能支持更多的连接。... 阅读详情

并发编程有三大核心问题:

  • 分工问题

  • 同步问题

  • 互斥问题

并发编程并不是一项孤立存在的技术,也不是脱离现实生活场景而提出的一项技术。

相反,并发编程是一项综合性的技术,同时,它与现实生活中的场景有着紧密的联系。

本文就对这三大核心问题进行简单的介绍。

分工问题

关于分工,比较官方的解释是:一个比较大的任务被拆分成多个大小合适的任务,这些大小合适的任务被交给合适的线程去执行。

分工强调的是执行的性能。

类比现实案例

可以类比现实生活中的场景来理解分工,例如,如果你是一家上市公司的 CEO,那么,你的主要工作就是规划公司的战略方向和管理好公司。就如何管理好公司而言,涉及的任务就比较多了。

这里,可以将管理好公司看作一个很大的任务,这个很大的任务可以包括人员招聘与管理、 产品设计、产品开发、产品运营、产品推广、税务统计和计算等。如果将这些工作任务都交给 CEO一个人去做,那么估计 CEO 会被累趴下的。CEO一人做完公司所有日常工作如图1所示。

图1 CEO 一人做完公司所有日常工作

如图1 所示,公司 CEO 一个人做完公司所有日常工作是一种非常不可取的方式,这将导致公司无法正常经营,那么应该如何做呢?

有一种很好的方式是分解公司的日常工作,将人员招聘与管理工作交给人力资源部,将产 品设计工作交给设计部,将产品开发工作交给研发部,将产品运营和产品推广工作分别交给运 营部和市场部,将公司的税务统计和计算工作交给财务部。

这样,CEO 的重点工作就变成了及时了解各部门的工作情况,统筹并协调各部门的工作, 并思考如何规划公司的战略。

公司分工后的日常工作如图2所示。

图2 公司分工后的日常工作

将公司的日常工作分工后,可以发现,各部门之间的工作是可以并行推进的。例如,在人力资源部进行员工的绩效考核时,设计部和研发部正在设计和开发公司的产品,与此同时,公司的运营人员正在和设计人员与研发人员沟通如何更好地完善公司的产品,而市场部正在加大力度宣传和推广公司的产品,财务部正在统计和计算公司的各种财务报表等。一切都是那么有条不紊。

所以,在现实生活中,安排合适的人去做合适的事情是非常重要的。映射到并发编程领域 也是同样的道理。

并发编程中的分工

在并发编程中,同样需要将一个大的任务拆分成若干比较小的任务,并将这些小任务交给 不同的线程去执行,如图3所示。

图3 将一个大的任务拆分成若干比较小的任务

在并发编程中,由于多个线程可以并发执行,所以在一定程度上能够提高任务的执行效率。

在并发编程领域,还需要注意一个问题就是:将任务分给合适的线程去做。也就是说,该由主线程执行的任务不要交给子线程去做,否则,是解决不了问题的。

这就好比一家公司的 CEO 将规划公司未来的工作交给一位产品开发人员一样,不仅不能规划好公司的未来,甚至会与公司的价值观背道而驰。

在 Java 中,线程池、Fork/Join 框架和 Future 接口都是实现分工的方式。在多线程设计模式中,Guarded Suspension 模式、Thread-Per-Message 模式、生产者—消费者模式、两阶段终止模式、Worker-Thread 模式和 Balking 模式都是分工问题的实现方式。

同步问题

在并发编程中,同步指一个线程执行完自己的任务后,以何种方式来通知其他的线程继续执行任务,也可以将其理解为线程之间的协作,同步强调的是执行的性能。

类比现实案例

可以在现实生活中找到与并发编程中的同步问题相似的案例。

例如,张三、李四和王五共同开发一个项目,张三是一名前端开发人员,他需要等待李四的开发接口任务完成再开始渲染 页面,而李四又需要等待王五的服务开发工作完成再写接口。

也就是说,任务之间是存在依赖关系的,前面的任务完成后,才能执行后面的任务。

在现实生活中,这种任务的同步,更多的是靠人与人之间的交流和沟通来实现的。例如,王五的服务开发任务完成了,告诉李四,李四马上开始执行开发接口任务。等李四的接口开发完成后,再告诉张三,张三马上调用李四开发的接口将返回的数据渲染到页面上。现实生活中 的同步模型如图4所示。

图4 现实生活中的同步模型

由图4可以看出,在现实生活中,张三、李四和王五的任务之间是有依赖关系的,张三渲染页面的任务依赖李四开发接口的任务完成,李四开发接口的任务依赖王五开发服务的任务完成。

并发编程中的同步

在并发编程领域,同步机制指一个线程的任务执行完成后,通知其他线程继续执行任务的方式,并发编程同步简易模型如图5所示。

图5 并发编程同步简易模型

由图5可以看出,在并发编程中,多个线程之间的任务是有依赖关系的。

线程 A 需要阻塞等待线程 B 执行完任务才能开始执行任务,线程 B 需要阻塞等待线程 C 执行完任务才能开始执行任务。线程 C 执行完任务会唤醒线程 B 继续执行任务,线程 B 执行完任务会唤醒线程 A 继续执行任务。

这种线程之间的同步机制,可以使用如下的 if 伪代码来表示。

if(依赖的任务完成){
  执行当前任务 
}else{
  继续等待依赖任务的执行 
} 

上述 if 伪代码所代表的含义是:当依赖的任务完成时,执行当前任务,否则,继续等待依 赖任务的执行。

在实际场景中,往往需要及时判断出依赖的任务是否已经完成,这时就可以使用 while 循 环来代替 if 判断, while 伪代码如下。

while(依赖的任务未完成){
  继续等待依赖任务的执行 
}  
执行当前任务

上述 while 伪代码所代表的含义是:如果依赖的任务未完成,则一直等待,直到依赖的任务完成,才执行当前任务。

在并发编程领域,同步机制有一个非常经典的模型——生产者—消费者模型。如果队列已满,则生产者线程需要等待,如果队列不满,则需要唤醒生产者线程;如果队列为空,则消费者线程需要等待,如果队列不为空,则需要唤醒消费者。

可以使用下面的伪代码来表示生产者—消费者模型。

生产者伪代码

while(队列已满){
  生产者线程等待 
}  
唤醒生产者

消费者伪代码

while(队列为空){
  消费者等待 
}  
唤醒消费者

在Java 中,Semaphore、Lock、synchronized.、CountDownLatch、CyclicBarrier、Exchanger 和 Phaser 等工具类或框架实现了同步机制。

互斥问题

在并发编程中,互斥问题一般指在同一时刻只允许一个线程访问临界区的共享资源。互斥强调的是多个线程执行任务时的正确性。

类比现实案例

互斥问题在现实中的一个典型场景就是交叉路口的多辆车汇入一个单行道,如图6所示。

图6 交叉路口的多辆车汇入一个单行道

从图6 可以看出,当多辆车经过交叉路口汇入同一个单行道时,由于单行道的入口只能容纳一辆车通过,所以其他的车辆需要等待前面的车辆通过单行道入口后,再依次有序通过单行道入口。这就是现实生活中的互斥场景。

并发编程中的互斥

在并发编程中,分工和同步强调的是任务的执行性能,而互斥强调的则是执行任务的正确性,也就是线程的安全问题。

如果在并发编程中,多个线程同时进入临界区访问同一个共享变量,则可能产生线程安全问题,这是由线程的原子性、可见性和有序性问题导致的。

而在并发编程中解决原子性、可见性和有序性问题的核心方案就是线程之间的互斥。

例如,可以使用JVM中提供的synchronized锁来实现多个线程之间的互斥,使用synchronized锁的伪代码如下。

修饰方法

public synchronized void methodName(){
   //省略具体方法 
}

修饰代码块

public void methodName(){
   synchronized(this){
      //省略具体方法
   }
} 

public void methodName(){
   synchronized(obj){
      //省略具体方法  
   }  
} 

public void methodName(){
   synchronized(ClassName.class){
      //省略具体方法
   }  
}

修饰静态方法

public synchronized static void staticMethodName(){
   //省略具体方法 
}

除了 synchronized 锁,Java 还提供了 ThreadLocal、CAS、原子类和以CopyOnWrite 开头的并发容器类、Lock 锁及读/写锁等,它们都实现了线程的互斥机制。

2021年不想被公司优化GitHub标星3.2K 01 如何理解高并发? 高并发意味着大流量,需要运用技术手段抵抗流量的冲击,这些手段好比操作流量,能让流量更平稳地被系统所处理,带给用户更好的体验。 我们常见的高并发场景有:淘宝的双11、春运时的抢票、微博大V的热点新闻等。除了这些典型事情,每秒几十万请求的秒杀系统、每天千万级的订单系统、每天亿级日活的信息流系统等,都可以归为高并发。 很显然,上面谈到的高并发场景,并发量各不相同,那到底多大并发才算高并发呢? 1、不能只看数字,要看具体的业务场景。不能说10W QPS的秒杀是高并发,而1W QPS的信息流就 阅读详情

相关推荐

【Java】Java实现100万+ 的高并发、高性能设计

现百万级并发编是一项综合性的技术,同时,它与现实生活中 的场景有着紧密的联系。搞懂并发编程有三大核心问题分工问题同步问题互斥问题本文就对这三大核心问题进行简单的介绍。

wjianwei666的专栏 605

这3个并发编程的核心,竟然还有人不知道?

点击关注公众号,实用技术文章及时了解并发编程并不是一项孤立存在的技术,也不是脱离现实生活场景而提出的一项技术。相反,并发编程是一项综合性的技术,同时,它与现实生活中 的场景有着紧密的联系。并发编程有三大核心问题:分工问题同步问题互斥问题本文就对这三大核心问题进行简单的介绍。1.分工问题关于分工,比较官方的解释是: 一个比较大的任务被拆分成多个大小合适的任务,这些大小合适的...

Java知音 559

LabVIEW数据采集-数字I/O/计数器

labview 数据采集 数字I/O 计数器

weixin_43781045的博客 5617

服务器百万并发的原理与实现

服务器百万并发的原理与实现

txh1873749380的博客 785

UE4 - 河流流体插件Fluid Flux

Fluid Flux可以模拟一定区域内的流体效果,由于使用顶视图所Capture的Heightfield信息,所以只支持室外开阔场景,不支持洞穴等室内场景;

GT的虚幻引擎文档 6666

实测对比:DeepSeek、豆包、千问三大AI模型生成测试用例谁更强?(附完整代码)

本文通过实测对比了DeepSeek、豆包、千问三大AI模型在生成测试用例方面的表现。文章提供了完整的Python代码实现,详细分析了各模型在用例完整性、准确性、边界覆盖及幻觉控制等维度的差异,并分享了工程化集成与多模型融合等优化策略,旨在帮助测试团队选择合适工具以提升工作效率。

ik6789012的博客 937

学并发编程,透彻理解这三个核心是关键

写在前面 上一篇文章这次走进并发的世界,请不要错过 给大家带了并发编程的开胃菜,接下来我们逐步上正餐,在吃正餐之前,我还要引用那首诗词: 「横看成岭侧成峰,远近高低各不同」,远看看轮廓,近看看细节,不断切换思维或视角来学习 远看并发,并发编程可以抽象成三个核心问题: 分工、同步/协作、互斥 如果你已经工作了,那么你一定听说过或者正在应用敏捷开发模式来交付日常的工作任务,我们就用你熟悉的流程来解释...

日拱一兵 2521

BUCK 电路详解

参考内容: 手撕Buck!Buck公式推导过程 电力电子的基础应用 《精通开关电源设计(第二版)》 Buck电源芯片输出有问题?检查这几样 原来PWM这么简单! BUCK 电路构建 根据高中所学习的物理知识可以很容易的想到,使用一个滑动变阻器即可实现降压和稳压的效果。当负载波动时,通过改变滑动变阻器的阻值,可以调节负载所获得的电压。但是使用滑动变阻器的劣势也很明显,大量的耗能会导致器件温度快速升高。 上面所提到的电路主要缺点在于导通器件(变阻器或三极管)本身存在耗能,那么有没有不会耗能的导通器件呢?

Guanngxu的博客 3985

并发编程的三个核心总结

点击上方"IT牧场",选择"设为星标"技术干货每日送达!写在前面上一篇文章这次走进并发的世界,请不要错过给大家带了并发编程的开胃菜,接下来我们逐步上正餐,在吃正餐之前,...

ITMuch的专栏 183

基于QT的华为网络摄像头二次开发

第一次使用华为的网络摄像头并进行二次开发,网上关于QT对华为网络摄像头的二次开发的文章很少,基于项目的需求做了一些工作,特此记录。 目标: 1、实时预览 2、手动控制录制视频 3、监听告警型号 4、实时获取元数据中的划定区域内的人数 摄像头型号如下: 准备工作: 在购买摄像头后,应当在官网下载对应的开发资料,如果需要权限,则联系华为的技术支持人员。下载资料如下: SDC Development Kit Demo 8.0.T9 SDK DEMO下载地址:https://bbs.hua

xumingyifrend的博客 3168

【Python开发者必看】Windows下Python版本管理器Pyenv安装使用,轻松管理Python版本的入门与进阶指南,从此告别Python环境不兼容的噩梦

好了,关于 【Python开发者必看】Windows下Python版本管理器Pyenv安装使用,轻松管理Python版本的入门与进阶指南,从此告别Python环境不兼容的噩梦 就写到这儿了,如果还有什么疑问或遇到什么问题欢迎扫码提问,也可以给我留言哦,我会一一详细的解答的。1、手动下载对应版本到 pyenv-win\install_cache 目录(如上手动操作安装步骤,文件名需匹配,如 python-3.10.0-amd64.exe)。该指令会列出,pyenv包管理工具所支持的所有python版本,

Spring Boot-Common On With You 851

Java线程安全的核心问题

几乎所有Java面试,都会问到这个问题。很多人的回答是:“多个线程访问同一个对象时,不需要做额外的同步处理也不会出问题。这个答案并不全面。当多个线程访问某个类时,这个类始终表现出正确的行为,那么这个类就是线程安全的。但问题是,什么是"正确的行为"?这正是面试官想考察的深度理解。count++;// 非原子操作看起来很简单的count++,实际上包含了三个操作:读取count值、将值加1、写回count。在多线程环境下,这三个操作可能交错执行,导致最终结果不正确。

佩奇的技术笔记 922

ORB-SLAM2算法4之KITTI开源数据集运行ORB-SLAM2生成轨迹并用evo工具评估轨迹

ORB-SLAM2算法1 已成功编译安装ORB-SLAM2到本地,本篇目的是用KITTI开源数据来运行ORB-SLAM2,并生成轨迹,最后用evo评估工具来评估ORB-SLAM2生成的轨迹和真值轨迹。

重点记录机器人和自动驾驶相关领域的技术,尤其是计算机视觉,视觉SLAM等,不仅有前言文献或必备算法的学习,也会有实际应用的点滴经验 2325

【并发编程】JUC并发编程

十万字长文深入源码讲解juc

Hanson的博客 831

【表面缺陷检测】基于yolov5的钢轨表面缺陷检测(附代码和数据集,Windows系统)

【表面缺陷检测】基于yolov5的钢轨表面缺陷检测(附代码和数据集,Windows系统)

学无止境、积少成多、厚积薄发 3981

蓝牙模块HM-10手册

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

【并发】并发编程三要素

并发编程是现代软件开发中不可避免的挑战之一。随着计算机硬件的发展,多核处理器和分布式系统变得越来越普遍,使得我们能够充分利用并行计算的潜力。然而,并发编程也引入了一系列的问题,如竞态条件、死锁和数据一致性等。为了有效地解决这些问题,理解并掌握并发编程的三要素是至关重要的。在并发编程的世界里,原子性、可见性和有序性是我们在设计和实现多线程应用时需要时刻关注的核心概念。通过保持操作的原子性,确保数据的可见性,以及维护代码的有序性,我们可以有效地避免许多潜在的错误和不一致性问题。

AliceNo的博客 1148

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Java 并发编程新范式

*** 虚拟线程 vs 平台线程* 平台线程:1:1 映射到操作系统线程,创建成本高* 虚拟线程:由 JVM 调度,可以创建数百万个*/// 创建虚拟线程});// 使用 ExecutorService});});Java 并发编程的新范式为我们提供了更强大、更易用的工具。虚拟线程让高并发编程变得简单,结构化并发让异步代码更清晰,Scoped Values 提供了更好的上下文管理方式。逐步采用虚拟线程替代传统线程池使用结构化并发管理并发任务。

alex_goden的博客 4068

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

聊聊并发编程——多线程之synchronized

多线程之synchronized

Elaine2391的博客 496
上一篇: 一点一点理解微服务
下一篇: 线程崩了,为什么不会导致 JVM 崩溃呢?如果是主线程呢?
JavaMonsterr
博客等级 码龄4年 211粉丝 481原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值