并发编程详解

一、核心原理
  1. CAS(Compare and Swap)

    • 机制:通过硬件指令(如cmpxchg)实现无锁原子操作,包含三个操作数(内存地址V、预期值A、新值B)。
    • ABA问题:值从A→B→A,CAS误判未变化。解决方案:添加版本号(如AtomicStampedReference)。
    • 应用AtomicIntegerReentrantLock底层实现。
  2. AQS(AbstractQueuedSynchronizer)

    • 核心结构:双向CLH队列 + volatile状态变量(state)。
    • 实现类
      • ReentrantLock:通过state记录重入次数。
      • CountDownLatchstate表示剩余计数。
    • 关键方法
      • acquire():尝试获取资源,失败则入队阻塞。
      • release():释放资源,唤醒后继节点。
  3. synchronized锁升级

    • 无锁 → 偏向锁:对象头记录线程ID,减少同一线程重入开销。
    • 偏向锁 → 轻量级锁:竞争时撤销偏向,通过CAS自旋获取锁。
    • 轻量级锁 → 重量级锁:自旋失败后,升级为OS互斥量(Mutex),线程进入阻塞。
    • 优化意义:减少直接使用重量级锁的性能损耗。
  4. volatile内存屏障

    • 可见性:写操作后插入StoreStore + StoreLoad屏障,强制刷新主内存。
    • 有序性:禁止指令重排序(通过LoadLoadLoadStore屏障)。
    • 局限性:不保证复合操作原子性(如i++需配合synchronizedAtomicInteger)。

二、线程池
  1. 7大参数

    • corePoolSize:核心线程数(常驻)。
    • maximumPoolSize:最大线程数(临时线程 = max - core)。
    • keepAliveTime:非核心线程空闲存活时间。
    • unit:时间单位(如TimeUnit.SECONDS)。
    • workQueue:任务队列(ArrayBlockingQueueLinkedBlockingQueue)。
    • threadFactory:自定义线程创建(如命名线程)。
    • handler:拒绝策略(如AbortPolicy)。
  2. 拒绝策略

    • AbortPolicy:默认策略,抛出RejectedExecutionException
    • CallerRunsPolicy:由提交任务的线程直接执行。
    • DiscardPolicy:静默丢弃新任务。
    • DiscardOldestPolicy:丢弃队列头部任务,重试提交。
  3. 动态调整核心线程数

    • 方法executor.setCorePoolSize(newSize)
    • 场景:根据流量高峰动态扩容/缩容,需结合监控系统(如Prometheus)。

三、并发容器
  1. ConcurrentHashMap分段锁演进

    • Java 7:分段锁(Segment),默认16段,每段独立加锁。
    • Java 8:CAS + synchronized锁桶(Node),链表转红黑树优化查询。
    • 性能对比:Java 8的锁粒度更细,并发度更高。
  2. CopyOnWriteArrayList适用场景

    • 原理:写时复制(复制整个数组),读操作无锁。
    • 优点:读性能极高,适合读多写极少(如黑白名单)。
    • 缺点:写操作开销大,数据一致性弱(最终一致)。

四、场景题:高并发订单系统设计
  1. 库存扣减

    • 方案一:Redis原子操作
      // 使用Lua脚本保证原子性 
      String script = "if redis.call('get', KEYS[1]) >= ARGV[1] then " 
      + "return redis.call('decrby', KEYS[1], ARGV[1]) " 
      + "else return -1 end"; 
      Long result = jedis.eval(script, Collections.singletonList("stock"), 1);

    • 方案二:数据库乐观锁
      UPDATE product SET stock = stock - 1, version = version + 1 WHERE id = #{productId} AND version = #{oldVersion};

  2. 分布式锁

    • Redis实现(RedLock)
      // 加锁 
      String lockKey = "order_lock_" + productId; String requestId = UUID.randomUUID().toString(); Boolean locked = jedis.set(lockKey, requestId, "NX", "PX", 30000); 
      // 解锁(Lua脚本保证原子性) 
      String script = "if redis.call('get', KEYS[1]) == ARGV[1] then " + "return redis.call('del', KEYS[1]) else return 0 end"; jedis.eval(script, Collections.singletonList(lockKey), requestId);

    • ZooKeeper实现:创建临时有序节点,最小节点获得锁,监听前序节点释放。
  3. 架构设计要点

    • 限流:网关层使用令牌桶(如Redis + Lua)。
    • 降级:库存预扣减后异步持久化,保证最终一致。
    • 分库分表:按用户ID哈希分表,避免热点问题。

通过深入理解上述知识点,并结合实际场景设计,能够在面试中展示出扎实的并发编程能力和系统设计思维。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

算法-图-dijkstra 最短路径

理论知识 dijkstra三部曲 朴素版dijkstra 模拟过程 堆优化版dijksra 经典模版例题 Dijkstra求最短路 I 参加科学大会(第六期模拟笔试)--模版题 网络延迟 ref 理论知识 最短路是图论中的经典问题即:给出一个有向图,一…

【leetcode hot 100 48】旋转图像

方法一:(原地旋转)对于矩阵中第 i 行的第 j 个元素,在旋转后,它出现在倒数第 i 列的第 j 个位置。matrix[row][col]在旋转后的新位置为matrix[col][n−row−1]。只要旋转四次就能回到原点。 class Solution {public vo…

Vue Hooks 深度解析:从原理到实践

Vue Hooks 深度解析:从原理到实践 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家!点我试试!! 文章目录 Vue Hooks 深度解析:从原理到实践一、背景…

ESP32S3读取数字麦克风INMP441的音频数据

ESP32S3 与 INMP441 麦克风模块的集成通常涉及使用 I2S 接口进行数字音频数据的传输。INMP441 是一款高性能的数字麦克风,它通过 I2S 接口输出音频数据。在 Arduino 环境中,ESP32S3 的开发通常使用 ESP-IDF(Espressif IoT Development Framew…

逐行拆解 C 语言:数据类型、变量

今日,我们即将踏上一段充满趣味与挑战的学习之旅,深度钻研数据类型的多样奥秘,解锁变量创建的实用技巧。不仅如此,还会邂逅两个实用的基础库函数,探索它们在程序中穿针引线的奇妙作用。同时,几个简洁却强大…

【Java数据结构】前K个高频单词

前K个高频单词 692. 前K个高频单词 - 力扣(LeetCode) 解决这个问题我们先得知道每个单词出现的次数,用map存储下来,然后将出现次数最多的通过建立小根堆解决top-K问题 ,重点是top-K的求取。 1.建立map 首先我们可以…

锂电池升压到5V并且可以锂电池充电的芯片SM5401

收拾旧物时发现一个旧台灯,正好又有一节锂电池,于是想改成:用锂电池给台灯供电(台灯是5V的),并且可以通过USB给锂电池充电。 于是找到了SM5401这个芯片。 SM5401 可以把锂电池电压升压成5V输出&#xff0c…

大模型工程师学习日记(十五):Hugging Face 模型微调训练(基于 BERT 的中文评价情感分析)

1. datasets 库核心方法 1.1. 列出数据集 使用 d atasets 库,你可以轻松列出所有 Hugging Face 平台上的数据集: from datasets import list_datasets# 列出所有数据集 all_datasets list_datasets()print(all_datasets)1.2. 加载数据集 你可以通过 l…

高考數學。。。

2024上 具体来说,直线的参数方程可以写为: x1t y−t z1t 二、简答题(本大题共5小题,每小题7分,共35分。) 12.数学学习评价不仅要关注结果评价,也要关注过程评价。简要说明过程评价应关注哪几个方面。…

Seurat - Guided Clustering Tutorial官方文档学习及复现

由于本人没有使用过Seurat4.0,而是直接使用的最新版。所以本文都是基于Seurat5.2.0(截止2025/3/6)来进行撰写。 参考的官方教程来进行学习(上图中的 Guided tutorial-2.700 PBMCs),肯定没有官方文档那么全面…

(undone) MIT6.S081 Lec14 File systems 学习笔记

url: https://mit-public-courses-cn-translatio.gitbook.io/mit6-s081/lec14-file-systems-frans Why Interesting 从一个问题开始:既然你每天都使用了文件系统,XV6的文件系统与你正在使用的文件系统有什么区别。接下来我会点名: 学生回答…

【C++进阶学习】第一讲——继承(下)---深入挖掘继承的奥秘

目录 1.隐藏 1.1隐藏的概念 1.2隐藏的两种方式 2.继承与友元 3、继承与静态成员 4.单继承和多继承 4.1单继承 4.2多继承 5.菱形继承 问题1:冗余性 问题2:二义性 6.虚拟继承 7.总结 1.隐藏 1.1隐藏的概念 在 C 中,继承是一种机制…

UI自动化:利用百度ocr识别解决图形验证码登录问题

相信大家在做自动化测试过程中都遇到过图形验证码的问题,最近我也是遇到了,网上搜了很多方法,最简单的方法无非就是去掉图形验证码或者设置一个万能验证码,但是这个都需要开发来帮忙解决,对于我们这种自学的人来说就不…

C/C++蓝桥杯算法真题打卡(Day1)

一、LCR 018. 验证回文串 - 力扣(LeetCode) 算法代码: class Solution { public:bool isPalindrome(string s) {int n s.size();// 处理一下s为空字符的情况if (n 0) {return true; // 修正拼写错误}// 定义左右指针遍历字符串int left …

蓝桥杯备考:动态规划路径类DP之矩阵的最小路径和

如题,要求左上角到右下角的最短路径,我们还是老样子按顺序做 step1:确定状态表示 f[i][j]表示(1,1)到(i,j)的最短距离 step2 :推导状态表达方程 step3:确定填表顺序,应该是从上到下,从左到右 step4:初始化 step5 找结果&#…

18类创新平台培育入库!长沙经开区2025年各类科技创新平台培育申报流程时间材料及申报条件

长沙经开区打算申报企业研发中心、技术创新中心、工程技术研究中心、新型研发机构、重点实验室、概念验证中心和中试平台、工程研究中心、企业技术中心、制造业创新中心、工业设计中心等创新平台的可先备案培育入库,2025年各类平台的认定将从培育库中优先推荐&#…

CyberDefenders----WebStrike Lab

WebStrike Lab 实验室链接 简介: 公司网络服务器上发现了一个可疑文件,在内联网中发出警报。开发团队标记了异常,怀疑存在潜在的恶意活动。为了解决这个问题,网络团队捕获了关键网络流量并准备了一个 PCAP 文件以供审查。您的任务是分析提供的 PCAP 文件以发现文件的出现…

【python】gunicorn配置

起因:因为cpu利用率低导致我去缩容,虽然缩容之后cpu利用率上升维持在60%左右,但是程序响应耗时增加了。 解释:因为cpu干这件活本身不累,但在干这件活的时候不能去干其他事情,导致并发的请求不能及时响应&am…

SSE vs WebSocket:AI 驱动的实时通信抉择

引言 近年来,基于 Transformer 的大模型推动了 AI 产业的飞速发展,同时带来了新的技术挑战: 流式传输 vs 批量返回:大模型生成的长文本若需一次性返回,会显著影响用户体验,实时推送成为必需。语音交互需求:语音助手要求毫秒级响应,而非等待用户完整输入后再返回结果。…

基于海思soc的智能产品开发(芯片sdk和linux开发关系)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 随着国产化芯片的推进,在soc领域,越来越多的项目使用国产soc芯片。这些soc芯片,通常来说运行的os不是linux&…