并发编程的三大核心问题

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

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

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

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

  • 分工问题
  • 同步问题
  • 互斥问题

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

1 分工问题

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

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

▊ 类比现实案例

可以类比现实生活中的场景来理解分工,例如,如果你是一家上市公司的 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 模式都是分工问题的实现方式。

2 同步问题

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

▊ 类比现实案例

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

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

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

在现实生活中,这种任务的同步,更多的是靠人与人之间的交流和沟通来实现的。例如,王五的服务开发任务完成了,告诉李四,李四马上开始执行开发接口任务。等李四的接口开发完成后,再告诉张三,张三马上调用李四开发的接口将返回的数据渲染到页面上。现实生活中 的同步模型如图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 等工具类或框架实现了同步机制。

3 互斥问题

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

▊ 类比现实案例

互斥问题在现实中的一个典型场景就是交叉路口的多辆车汇入一个单行道,如图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的专栏 607

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

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

Java知音 559

泛微E8流程监控指南:如何用SQL实时追踪审批节点状态?

本文详细介绍了如何利用SQL实时监控泛微E8系统中的审批流程状态,包括核心数据表结构解析、全链路监控SQL实战以及智能预警机制设计。通过数据库直接查询和状态关联分析,帮助企业快速定位卡顿节点,提升流程效率。适用于需要优化OA系统流程管理的企业IT人员和业务主管。

weixin_30687051的博客 440

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

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

txh1873749380的博客 786

【论文详解】AlphaGenome——Sequence-to-Multimodal-Genome-Track

**AlphaGenome** 是由 **Google DeepMind** 于 2025 年 6 月发布的突破性 AI 模型,专门用于预测非编码区遗传变异的功能效应。该模型采用受 **U-Net** 启发的卷积架构结合 **Transformer** 模块,创新性地解决了传统模型在输入序列长度与预测分辨率之间的核心矛盾——能够在 **1M 碱基对的超长上下文** 下实现 **单核苷酸分辨率** 的精准预测。

zwhszdx的博客 963

abaqus 根据坐标施加载荷- Analytical Field 载荷映射

在一些类型的分析中,需要将按位置分布的载荷施加到结构上,比如流体分析导出了结构的气动载荷、或者温度载荷,需要将压强分布、温度分布载荷施加到固体上。这种分析可以使用abaqus中的Analytical Field实现。 1 例子 1.1 结构 一个100*100mm的面,面的载荷分布函数为p=(x2+y2)0.5/((20.5)*100) MPa,即(0, 0)的压强为0,(100, 100)的压强为1。 1.2 载荷 载荷函数:p=(x^2+y^2)^0.5/((2^0.5)*100) in exce.

shengyutou的博客 2万+

一分钟理解:并发编程的三大核心问题

江湖人都说,并发编程的三大核心问题分别是:有序性、可见性、原子性。 What???

luopeng_tr的博客 452

BK3296蓝牙音频SoC深度评测:如何用这颗芯片打造超低功耗TWS耳机?

本文深度评测BK3296蓝牙音频SoC在TWS耳机中的应用,重点解析其22nm工艺带来的超低功耗优势(A2DP模式仅2.8mA)和3×3mm封装设计。通过芯片架构分析、双麦降噪调优及开发套件使用指南,为工程师提供打造高性能TWS耳机的完整解决方案,显著提升续航和音频质量。

rice5的博客 659

【Java并发编程实战】并发编程的三大核心问题?

理解这三大问题是掌握Java并发编程的基础,只有理解了这些问题,才能正确选择和使用并发工具。线程A执行到步骤2时,线程B看到instance不为null,直接返回未完全初始化的对象。一个或多个操作,要么全部执行成功,要么全部不执行,不会出现执行到一半的情况。volatile、synchronized、Atomic类。一个线程对共享变量的修改,另一个线程不能立即看到。synchronized、Lock、Atomic类。程序执行的顺序与代码编写的顺序不一致。

gaochufukanyongren的博客 789

Unity类银河战士恶魔城学习总结(P103之前 Enemy相关 , 骷髅战士,状态机,敌人状态,)

udemy的Alex银河战士恶魔城,记录我自己的学习,代码会逐渐每一p更新,仅供参考学习。

suzh1qian的博客 1633

深度学习(五)迁移学习(实战:新数据预测+vgg16和聚类预测)

6、成功引入PCA数据降维技术,剔除了数据中的噪音信息、降低了模型复杂度、减少了模型训练时间,并最终提高了模型表现;gen=datagen.flow_from_directory(path,target_size=(224,224),batch_size=2,save_to_dir=dst_path,save_prefix='gen',save_format='jpg') # 生成图片大小224*224,bs产生多少组图像,存储路径和前缀。1、通过使用新数据,实现了模型的2次训练,达到了较好的预测效果;

weixin_37699342的博客 775

并发编程的三大核心问题(荣耀典藏版)

主要介绍了并发编程中的三大核心问题:分工、同步和互斥,并列举了现实生活中的场景进行类比,以便读者理解这三大核心问题。

人生若只初相见@的博客 1万+

使用C#实现的多人语音视频系统:WebSocket与WebRTC集成

通过上述的代码示例,我们可以使用C#编写一个多人语音视频系统,该系统集成了WebSocket和WebRTC技术。当然,这只是一个简单的示例,实际的多人语音视频系统可能需要更多的功能和优化。通过结合这两种技术,我们可以实现实时的语音和视频通信,支持多人同时参与。在上述代码中,我们创建了一个WebSocket服务器,监听在本地的8080端口,并创建了一个WebRTC连接。接下来,我们将详细介绍如何使用C#编写一个多人语音视频系统,包括使用WebSocket建立连接和使用WebRTC进行实时通信。

TjsReact的博客 1635

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

并发编程有三大核心问题分工问题同步问题互斥问题并发编程并不是一项孤立存在的技术,也不是脱离现实生活场景而提出的一项技术。相反,并发编程是一项综合性的技术,同时,它与现实生活中的场景有着紧密的联系。本文就对这三大核心问题进行简单的介绍。...

JavaMonsterr的博客 177

uniapp - 强力解决H5网页浏览器跨域问题,如何解决uniapp请求接口在浏览器跨域问题,UniApp H5 跨域代理配置详细教程完美解决所有uniapp跨域(调用第三方接口或服务器api跨域)

uni-app 跨域,uniApp解决h5跨域问题,解决uni-app请求接口在浏览器跨域问题,uni.request请求跨域问题解决方案,uni-app-跨域解决方法,彻底解决uniapp发布为H5的跨域问题,uniapp H5页面设置跨域请求_uniapp h5跨域配置,uniapp开发 H5 解决跨域问题,uniApp请求解决跨域问题,uniapp request如何实现前端请求跨域,解决uniapp调试过程中的请求跨域和环境配置,Uniapp调用外部api接口跨域请求,uni-app发布H5页面跨域

🏆 前端领域优质创作者 5357

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

Java并发编程之并发编程三大核心问题

个人博客请访问http://www.x0100.top 写在前面 编写并发程序是比较困难的,因为并发程序极易出现Bug,这些Bug有都是比较诡异的,很多都是没办法追踪,而且难以复现。 要快速准确的发现并解决这些问题,首先就是要弄清并发编程的本质,并发编程要解决的是什么问题。 本文将带你深入理解并发编程要解决的三大问题:原子性、可见性、有序性。 补充知识 硬件的发展中,一直存在一个矛盾,CPU、内存、I/O设备的速度差异。 速度排序:CPU >> 内存 >> ...

HelloWorld搬运工 703

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

【并发编程实战】7、并发三大核心问题全解析:安全性、活跃性与性能优化实战

Java并发编程三大核心问题解析 本文系统分析了Java并发编程中的关键挑战: 安全性问题:确保程序正确执行,避免数据竞争和竞态条件。通过同步机制(synchronized)、原子类(Atomic)和锁(Lock)保证原子性、可见性和有序性。 活跃性问题:防止程序陷入死锁、活锁和饥饿状态。解决方案包括锁顺序化、超时机制、资源有序分配等策略。 性能优化:在保证正确性的前提下提升并发效率。关键技术包括减少锁粒度、读写分离、无锁编程和使用并发容器。 文章通过代码示例、对比表格和示意图,详细展示了各类问题的表现特征

2025博客之星Top81。专注AI工程化与架构实战。从分布式思维到模型部署,用工程化视角为你厘清AI落地的真实路径。 1111

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

并发编程的三大核心问题(三)

类比现实案例 并发编程中的分工 同步问题 类比现实案例 并发编程中的同步 互斥问题 类比现实案例 并发编程中的互斥

qq_41934990的博客 245

java并发编程_「原创」Java并发编程系列02 | 并发编程三大核心问题

写在前面编写并发程序是比较困难的,因为并发程序极易出现Bug,这些Bug有都是比较诡异的,很多都是没办法追踪,而且难以复现。要快速准确的发现并解决这些问题,首先就是要弄清并发编程的本质,并发编程要解决的是什么问题。本文将带你深入理解并发编程要解决的三大问题:原子性、可见性、有序性。补充知识硬件的发展中,一直存在一个矛盾,CPU、内存、I/O设备的速度差异。速度排序:CPU >> 内存 ...

weixin_33915154的博客 89

并发编程三大核心问题的诞生:可见性、原子性和有序性

可见性 CPU缓存导致的可见性问题 描述 可见性指的是一个线程对共享变量的修改,另一个线程能够立刻看到。单核心情况下,所有线程操作的都是同一个CPU的缓存,一个线程对缓存的写,对另一个线程来说是可见的,但是在多核心情况下,每颗CPU都有自己的缓存,当线程分别在不同的CPU上操作时,共享变量一致性问题就出现了,这时一个线程对共享变量的操作对另一个线程而言就不具备可见性 图解 原子性 线程切换带来...

LIUUUU 499

Java并发编程核心:JMM与三大并发问题

并非真实存在的物理内存,而是Java虚拟机(JVM)定义的一套抽象规范——它规定了所有变量(实例变量、静态变量、数组元素)的存储位置、线程如何访问这些变量,以及变量在内存中的读写规则。核心目的:解决多线程环境下,CPU缓存、指令重排序导致的内存可见性、原子性、有序性问题,保证多线程并发访问的安全性。为什么需要JMM?现代计算机为了提升性能,会在CPU和主内存之间增加高速缓存(Cache),同时CPU会对指令进行重排序(优化执行效率)。

2503_92804185的博客 209

java 多线程 核心_JAVA多线程之并发编程三大核心问题

1,编译器优化的重排序:编译器在不改变单线程程序语义的前提下,可以重新安排语句的执行顺序。2,指令级并行的重排序:处理器将多条指令重叠执行,如果不存在数据依赖性,处理器可以改变语句对应机器指令的执行顺序。3,内存系统的重排序:处理器使用缓存和读/写缓冲区,使得加载和存储操作看上去可能实在乱序执行。重排序需要遵守一定的规则:重排序遵守数据依赖性:如果两个操作访问同一个变量,且这两个操作中有一个为写操...

weixin_36276175的博客 223

Java学习如何进阶?

并发编程的目的是为了让程序运行得更快,但同样也伴随着很多挑战!如果你是Java开发,想要涨薪并提高自己的技术水平,那并发编程可得好好搞一搞!如果有朋友需要这套并发资料,只需要点击文末小卡片即可!

m0_74822999的博客 470

《菜鸟读并发》并发编程三个核心问题和三个主要BUG源头你知多少?

并发编程的第一原则,那就是不要写并发程序,所以编写正确的并发程序是一件极困难的事情,但要快速而又精准地解决“并发”类的疑难杂症,就要理解这件事情的本质,追本溯源,深入分析这些Bug的源头在哪里。 并发编程三个核心问题和三个主要BUG源头,思维导图如下: 前戏 我们知道我们的的CPU、内存、I/O设备都在不断快速的迭代,不断朝着更快的方向努力。但是,在这个快速发展的过程中,有一个核心矛盾一直存...

qq_25843323的博客 3万+
上一篇: 三张图带你彻底理解 RocketMQ 事务消息
下一篇: SpringBoot+Nacos+Kafka实现微服务流编排
JavaMonsterr
博客等级 码龄4年 211粉丝 481原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值