Java 并发在项目中的使用场景

news2025/1/16 1:04:35

1、并发编程的三个核心问题:

(1)分工:所谓分工指的是如何高效地拆解任务并分配给线程

(2)同步:而同步指的是线程之间如何协作

(3)互斥:互斥则是保证同一时刻只允许一个线程访问共享资源

(4)应用:Java SDK 并发包很大部分内容都是按照这三个维度组织的,例如 Fork/Join 框架就是一种分工模式,CountDownLatch 就是一种典型的同步方式,而可重入锁则是一种互斥手段。

2、学习方法:

(1)跳出来,看全景:简历一张全景图

① 分工:

其实这就是生产者 - 消费者模式的一个优点,生产者一个一个地生产数据,而消费者可以批处理,这样就提高了性能。

② 同步:

a、一个线程执行完了一个任务,如何通知执行后续任务的线程开工

b、工作中遇到的线程协作问题,基本上都可以描述为这样的一个问题:当某个条件不满足时,线程需要等待,当某个条件满足时,线程需要被唤醒执行。例如,在生产者 - 消费者模型里,也有类似的描述,“当队列满时,生产者线程等待,当队列不满时,生产者线程需要被唤醒执行;当队列空时,消费者线程等待,当队列不空时,消费者线程需要被唤醒执行。

c、在 Java 并发编程领域,解决协作问题的核心技术是管程,上面提到的所有线程协作技术底层都是利用管程解决的。管程是一种解决并发问题的通用模型,除了能解决线程协作问题,还能解决下面我们将要介绍的互斥问题。可以这么说,管程是解决并发问题的万能钥匙。

③ 互斥:

a、线程安全,而导致不确定的主要源头是可见性问题、有序性问题和原子性问题,

b、所谓互斥,指的是同一时刻,只允许一个线程访问共享变量。

c、Java SDK 里提供的 ReadWriteLock、StampedLock 就可以优化读多写少场景下锁的性能。

d、除此之外,还有一些其他的方案,原理是不共享变量或者变量只允许读。这方面,Java 提供了 Thread Local 和 final 关键字,还有一种 Copy-on-write 的模式。

3、钻进去,看本质

我认为工程上的解决方案,一定要有理论做基础。

4、并发程序幕后的故事

(1)CPU、内存、I/O 设备都在不断迭代,不断朝着更快的方向努力。有一个核心矛盾一直存在,就是这三者的速度差异。

(2)为了合理利用 CPU 的高性能,平衡这三者的速度差异:

(3)CPU 增加了缓存,以均衡与内存的速度差异;操作系统增加了进程、线程,以分时复用 CPU,进而均衡 CPU 与 I/O 设备的速度差异;编译程序优化指令执行次序,使得缓存能够得到更加合理地利用。

(4)并发问题

a、源头之一:缓存导致的可见性问题

一个线程对共享变量的修改,另外一个线程能够立刻看到,我们称为可见性。

多核时代,每颗 CPU 都有自己的缓存,这时 CPU 缓存与内存的数据一致性就没那么容易解决了

b、源头之二:线程切换带来的原子性问题

操作系统允许某个进程执行一小段时间,例如 50 毫秒,过了 50 毫秒操作系统就会重新选择一个进程来执行(我们称为“任务切换”),这个 50 毫秒称为“时间片”。

在一个时间片内,如果一个进程进行一个 IO 操作,例如读个文件,这个时候该进程可以把自己标记为“休眠状态”并出让 CPU 的使用权,待文件读进内存,操作系统会把这个休眠的进程唤醒,唤醒后的进程就有机会重新获得 CPU 的使用权了。

这里的进程在等待 IO 时之所以会释放 CPU 使用权,是为了让 CPU 在这段等待时间里可以做别的事情,这样一来 CPU 的使用率就上来了;此外,如果这时有另外一个进程也读文件,读文件的操作就会排队,磁盘驱动在完成一个进程的读操作后,发现有排队的任务,就会立即启动下一个读操作,这样 IO 的使用率也上来了。

早期的操作系统基于进程来调度 CPU,不同进程间是不共享内存空间的,所以进程要做任务切换就要切换内存映射地址,而一个进程创建的所有线程,都是共享一个内存空间的,所以线程做任务切换成本就很低了。现代的操作系统都基于更轻量的线程来调度,现在我们提到的“任务切换”都是指“线程切换”。

高级语言里一条语句往往需要多条 CPU 指令完成,例如上面代码中的count += 1,至少需要三条 CPU 指令。

指令 1:首先,需要把变量 count 从内存加载到 CPU 的寄存器;

指令 2:之后,在寄存器中执行 +1 操作;

指令 3:最后,将结果写入内存(缓存机制导致可能写入的是 CPU 缓存而不是内存)。

操作系统做任务切换,可以发生在任何一条 CPU 指令执行完,是的,是 CPU 指令,而不是高级语言里的一条语句。

我们把一个或者多个操作在 CPU 执行的过程中不被中断的特性称为原子性。CPU 能保证的原子操作是 CPU 指令级别的,而不是高级语言的操作符,这是违背我们直觉的地方。因此,很多时候我们需要在高级语言层面保证操作的原子性。

c、源头之三:编译优化带来的有序性问题


public class Singleton {
  static Singleton instance;
  static Singleton getInstance(){
    if (instance == null) {
      synchronized(Singleton.class) {
        if (instance == null)
          instance = new Singleton();
        }
    }
    return instance;
  }
}

特意提到缓存导致的可见性问题,线程切换带来的原子性问题,编译优化带来的有序性问题

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

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

相关文章

本科大数据专业能找到大数据开发的工作么

本科大数据专业能不能找到大数据开发的工作取决于你在校期间大数据学科学习的怎么样~ 目前大二就还有时间去学习,趁着空余时间找个完整的学习路线去学习,争取能够在校招的时候就找到心仪的工作技术过关的话是完全没有问题的,而且加上你还有兴…

PythonWeb开发基础(三)类Flask框架请求封装

课程地址:Python 工程师进阶技术图谱 文章目录类Flask框架请求封装HTTP请求解析的python实现1、解析查询字符串2、多值问题使用webob库解析请求Bug记录bug:AttributeError: module cgi has no attribute parse_qs类Flask框架请求封装 Web服务器 本质是…

【C++提高编程】list 容器详解(附测试用例与结果图)

目录1. list容器1.1 list基本概念1.2 list构造函数(初始化)1.3 list 赋值和交换1.4 list 大小操作1.5 list 插入和删除1.6 list 数据存取1.7 list 反转(reverse)、排序(sort)和去重(unique&…

电脑技巧:电脑状态监控神器TrafficMonitor介绍

有的时候我们为了解决某些电脑问题,需要监控电脑的实时网速、CPU、内存等的占用情况。一般情况下我们可以打开电脑任务管理器,就可以实时监控硬件状态,但如果查看频率较高的话,需要每次进入任务管理器就显得比较麻烦。今天小编分享…

【漏洞修复】 CVE Linux 系统应用漏洞修复笔记

这里写自定义目录标题说明SSL/TLS协议信息泄露漏洞(CVE-2016-2183)漏洞信息解决办法验证方法修复步骤说明查询当前使用的openssl版本号下载并安装新版本的openssl替换nginx中使用的openssl到最新版说明 此文章主要记录工作中遇到的漏洞以及修复过程。 SSL/TLS协议信息泄露漏洞…

【LeetCode】员工的重要性 | 图像渲染 | 岛屿问题

​🌠 作者:阿亮joy. 🎆专栏:《阿亮爱刷题》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉员工的重…

力扣SQL刷题4

目录1158. 市场分析 I1280. 学生们参加各科测试的次数1174. 即时食物配送 II585. 2016年的投资1158. 市场分析 I 题型:表1和表2连接时,如何把没有对应数据输出来。即表1中所有id列对应的表2数据输出,没用的输出0 解答1:left join…

【Linux】权限

🔥🔥 欢迎来到小林的博客!!       🛰️博客主页:✈️小林爱敲代码       🛰️博客专栏:Linux之路       🛰️社区: 进步学堂       …

关于软考的一些前期准备

国家软考的中级职称证书,含金量较高且没有报考资质限制 报名时间和考试时间具体请看官网:中国计算机技术职业资格网 不同的资格证书时间和要求不一样,注意查看 上半年: 下半年: 下半年: 软件评测师考试说…

Spring Boot 中事半功倍的一些工具类

系列文章地址:https://blog.csdn.net/perfect2011/article/details/124603278在日常开发中经常有这样那样的小功能需要实现,这些一般会作为工具类存在,在项目中有一些通用的功能,Spring内置了需要工具类,而且经过了大量…

京东一面:20种异步,你知道几种? 含协程

背景说明: 异步,作为性能调优核心方式之一,经常被用于各种高并发场景。 很多场景多会使用到异步,比如: 场景1: 超高并发 批量 写 mysql 、批量写 elasticSearch 场景2: 超高并发 批量 IO 场景…

30分钟掌握 Hive SQL 优化(解决数据倾斜)

Hive SQL 几乎是每一位互联网分析师的必备技能,相信每一位面试过大厂的童鞋都有被面试官问到 Hive 优化问题的经历。所以掌握扎实的 HQL 基础尤为重要,既能帮分析师在日常工作中“如鱼得水”提高效率,也能在跳槽时获得一份更好的工作 offer。…

【23种设计模式】设计模式介绍与分类

前言 本文为 【23种设计模式】设计模式介绍与分类 相关知识介绍,下边将对什么是设计模式,设计模式的分类与23种设计模式的关键点进行详尽介绍~ 📌博主主页:小新要变强 的主页 👉Java全栈学习路线可参考:【…

蓝桥算法两周训练营--Day2:DP

T1:P1048 [NOIP2005 普及组] 采药 - 洛谷 代码: 1、二维Dp: package 蓝桥算法两周训练营__普及组.Day2_dp;import java.util.Scanner;/*** author yx* date 2023-02-05 13:16*/ public class t1 {// P1048 [NOIP2005 普及组] 采药 - 洛…

java春招大厂面试,差点让面试官给我聊挂喽!

作者:小傅哥 博客:https://bugstack.cn 沉淀、分享、成长,让自己和他人都能有所收获! 八股文整的挺好,算法也刷的够多,但问到项目就很拉胯。 这可能是现在大部分没有实际项目经验的校招生和一直从事边角料开…

环境变量【Linux】

文章目录:Linux环境变量介绍常用的环境变量如何查看环境变量命令搜索路径PATH与环境变量相关的命令环境变量的组织方式通过代码的方式获取环境变量通过系统调用获取或设置环境变量环境变量的全局属性(继承)Linux环境变量介绍 环境变量&#…

【王道数据结构】第五章(下) | 树 | 二叉树

目录 一、树的存储结构 1、双亲表示法(顺序存储): 2、孩子表示法(顺序链式) 3、孩子兄弟表示法(链式存储) 二、树、森林的遍历 1、树的先根遍历 2、树的后根遍历 3、层序遍历(队列实现) 4、森林的遍历 三、二叉排序树 …

电子技术——IC偏置-电流源、电流镜、电流舵

电子技术——IC偏置-电流源、电流镜、电流舵 IC偏置设计基于恒流源技术。在IC中的一个特定的区域,会生成一个精确的DC电流,这称为 参考电流 ,之后通过电流镜复制到各个所需支路,并且通过电流舵进行电流转向。这项技术为IC的多级放…

知识图谱实战(01):从0-1搭建图片服务器

作者:艾文编程职业:程序员,BAT大厂资深工程师摘要:搜索/推荐场景下给用户展示大量的图片信息,那么这些数据是通过专门的图片服务器来访问的。 我们在基于知识图谱的智能搜索系统中,对搜索出来的每条记录都有…

支付系统核心架构设计思路(万能通用)

文章目录1. 支付系统总览核心系统交互业务图谱2. 核心系统解析交易核心交易核心基础交易类型抽象多表聚合 & 订单关联支付核心支付核心总览支付行为编排异常处理渠道网关资金核算3. 服务治理平台统一上下文数据一致性治理CAS校验幂等 & 异常补偿对账准实时对账DB拆分异…