开始改变第三天 Java并发(1)

2025-12-12 0 460

深入Java并发世界:从核心概念到实战精粹 | 技术笔记

引言:为何并发如此重要?

在多核处理器成为主流的今天,能否充分利用硬件资源构建高效、可靠的高并发应用,已成为衡量一名后端开发者功底的关键。然而,并发编程并非坦途,它充满了线程安全、死锁、内存可见性、原子性等诸多挑战。理解其内在机理,是驯服这头“猛兽”的不二法门。

本文将围绕五大核心知识点,带你由表及里,构建坚实的Java并发知识体系。


第一部分:并发基石 —— 线程基础与核心概念

核心思想: 万物皆有源,理解并发必须先理解线程本身。

  • 线程的创建与生命周期:

    • 继承 Thread 类 vs. 实现 Runnable / Callable 接口。后者更佳,因为实现了接口分离,便于任务共享。
    • 线程状态:NEW(新建)、RUNNABLE(可运行)、BLOCKED(阻塞)、WAITING(等待)、TIMED_WAITING(超时等待)、TERMINATED(终止)。深刻理解状态转换是诊断多线程问题的基础。
  • 关键概念:

    • 线程安全: 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或者在调用方进行任何其他协调操作,调用这个对象的行为都可以获得正确的结果,那就称这个对象是线程安全的。
    • 竞态条件: 计算的正确性取决于多个线程的交替执行时序。
    • 共享与同步: 堆内存、方法区内存是线程共享的,而栈内存和程序计数器是线程私有的。为了解决共享带来的问题,引入了 synchronized 等同步机制。

学习心得: 这一部分是所有并发知识的“地基”,务必清晰地理解每个状态的意义和转换条件,这是后续分析复杂锁问题(如死锁)的前提。


第二部分:内存模型的灵魂 —— 深入理解MESI与volatile

核心思想: 解决可见性与有序性问题,必须深入到CPU缓存和内存屏障的层面。

  • JMM(Java内存模型): JMM是一个抽象规范,它规定了线程如何以及何时可以看到其他线程修改过的共享变量,以及在必要时如何同步地访问共享变量。它定义了主内存工作内存之间的关系。

  • MESI协议: 这是理解 volatile 和 synchronized 底层实现的钥匙。

    • 它是一种CPU缓存一致性协议。CPU缓存行有四种状态:
      • M(Modified,修改): 缓存行是脏的,与主内存值不同。
      • E(Exclusive,独占): 缓存行是干净的,与主内存一致,且只有本核心有副本。
      • S(Shared,共享): 缓存行是干净的,与主内存一致,但多个核心可能有副本。
      • I(Invalid,无效): 缓存行数据无效,不能使用。
    • 通过这套状态机协议,CPU在读写数据时,通过总线消息来协调,保证了多个核心缓存数据的一致性。
  • volatile关键字:

    • 语义1:保证可见性。 对一个volatile变量的写,会立刻刷新回主内存,并导致其他CPU中对应的缓存行失效,迫使其他线程在读取时必须从主内存重新加载。
    • 语义2:禁止指令重排序。 通过插入内存屏障 来实现。
    • 底层实现: 正是JVM在编译时在volatile读写操作前后加入特定内存屏障,这些屏障会触发CPU的MESI协议或类似机制,从而实现了上述两大语义。

学习心得: 以前只知道volatile能保证可见性,但不知其所以然。理解了MESI和内存屏障后,才真正明白它的魔力来源。它不保证原子性,所以不适合 i++ 这样的场景。


第三部分:锁的艺术 —— 精通ReentrantLock

核心思想: synchronized 是“自动挡”,而 ReentrantLock 是“手动挡”,提供了更灵活、更强大的锁控制。

  • 与synchronized对比:

    • 可中断: lockInterruptibly() 可以响应中断,避免死锁。
    • 尝试非阻塞: tryLock() 可以立即返回,避免长时间等待。
    • 公平性: 可以创建公平锁(按申请顺序获取锁),虽然通常性能较低。
    • 绑定多个条件: 一个 ReentrantLock 可以绑定多个 Condition 对象,实现更精细的线程等待/唤醒。
  • AQS(AbstractQueuedSynchronizer):

    • 这是 ReentrantLockCountDownLatchSemaphore 等同步器的核心框架。
    • 其内部维护了一个 volatile int state(代表资源状态)和一个 FIFO线程等待队列(CLH队列的变体)。
    • 核心方法是 acquire()release()。子类通过重写 tryAcquiretryRelease 方法来定义具体的资源获取和释放逻辑。

学习心得: 学习 ReentrantLock 绝不能止步于API调用,必须深入到AQS层面。理解了AQS,就等于拿到了Java并发工具包的“万能钥匙”。


第四部分:线程隔离的魔法 —— ThreadLocal原理与陷阱

核心思想: 用空间换时间,为每个线程创建变量的副本,避免共享,从而实现线程安全。

  • 核心原理:

    • 每个 Thread 对象内部都有一个 ThreadLocalMap 类型的 threadLocals 变量。
    • ThreadLocalMapKey是ThreadLocal对象本身(弱引用),Value是存储的变量副本。
    • get()/set() 方法操作的是当前线程ThreadLocalMap,因此天然线程隔离。
  • 经典场景:

    • 用户会话信息(如User对象)传递,避免在方法间层层传递参数。
    • 数据库连接、事务管理(如Spring的 @Transactional)。
    • 日期格式化类 SimpleDateFormat 的线程安全包装。
  • 内存泄漏陷阱:

    • 根源: Key是弱引用,会在GC时被回收,但Value是强引用。如果线程长时间运行(如线程池中的线程)且不再使用该 ThreadLocal,就会导致Value无法被访问,却也无法被回收,造成内存泄漏。
    • 解决方案: 在使用完毕后,必须调用 threadLocal.remove() 方法,手动清除Entry。

学习心得: ThreadLocal 是解决特定场景并发问题的利器,但“能力越大,责任越大”,务必记得及时清理,养成良好的编程习惯。


第五部分:容器的并发之道 —— HashMap与ConcurrentHashMap

核心思想: 不同的并发场景下,需要选择不同并发级别的容器。

  • HashMap的并发死穴:

    • 在JDK7中,多线程并发扩容可能导致环形链表,引起CPU 100%。
    • 在JDK8中,虽然解决了死循环问题,但仍有数据覆盖、丢失等线程安全问题。结论:HashMap在任何情况下都不适用于多线程环境。
  • ConcurrentHashMap(JDK8+)的精妙设计:

    • 抛弃分段锁(JDK7): 采用 Node数组 + 链表 + 红黑树 结构,锁的粒度更细,直接锁住数组的每个桶(桶的头节点)。
    • 并发控制:
      • CAS + synchronized 初始化、插入头节点使用CAS无锁编程。对桶的头节点使用 synchronized 加锁,锁粒度小,性能极高。
      • sizeCtl等控制变量: 配合volatile读写和CAS,实现高效的并发扩容和大小统计。
    • 扩容: 支持多线程协助扩容,提升效率。

学习心得:Hashtable(全表锁)到 ConcurrentHashMap(分段锁)再到 ConcurrentHashMap(桶级别锁),这演进历程本身就是一部锁优化教科书。理解CHM,就能深刻体会如何在高性能和高并发之间找到平衡。


总结与展望

并发编程的学习是一个螺旋式上升的过程。从宏观的线程概念出发,深入到CPU级别的缓存一致性(MESI),再上到Java语言层面的锁和同步工具(AQS),接着是线程隔离的ThreadLocal,最后将这些知识融会贯通,理解顶级并发容器ConcurrentHashMap的设计哲学。

这条路径,不仅是知识的积累,更是思维方式的锤炼——从“会用”到“懂原理”,再到“能优化”。希望这篇笔记能为你照亮前行的道路,共勉!


版权声明: 本文为个人学习笔记,部分原理总结自公开课程与技术文档,如有侵权请联系删除。欢迎交流,转载请注明出处。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

申明:本文由第三方发布,内容仅代表作者观点,与本网站无关。对本文以及其中全部或者部分内容的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。本网发布或转载文章出于传递更多信息之目的,并不意味着赞同其观点或证实其描述,也不代表本网对其真实性负责。

左子网 编程相关 开始改变第三天 Java并发(1) https://www.zuozi.net/35741.html

常见问题
  • 1、自动:拍下后,点击(下载)链接即可下载;2、手动:拍下后,联系卖家发放即可或者联系官方找开发者发货。
查看详情
  • 1、源码默认交易周期:手动发货商品为1-3天,并且用户付款金额将会进入平台担保直到交易完成或者3-7天即可发放,如遇纠纷无限期延长收款金额直至纠纷解决或者退款!;
查看详情
  • 1、描述:源码描述(含标题)与实际源码不一致的(例:货不对板); 2、演示:有演示站时,与实际源码小于95%一致的(但描述中有”不保证完全一样、有变化的可能性”类似显著声明的除外); 3、发货:不发货可无理由退款; 4、安装:免费提供安装服务的源码但卖家不履行的; 5、收费:价格虚标,额外收取其他费用的(但描述中有显著声明或双方交易前有商定的除外); 6、其他:如质量方面的硬性常规问题BUG等。 注:经核实符合上述任一,均支持退款,但卖家予以积极解决问题则除外。
查看详情
  • 1、左子会对双方交易的过程及交易商品的快照进行永久存档,以确保交易的真实、有效、安全! 2、左子无法对如“永久包更新”、“永久技术支持”等类似交易之后的商家承诺做担保,请买家自行鉴别; 3、在源码同时有网站演示与图片演示,且站演与图演不一致时,默认按图演作为纠纷评判依据(特别声明或有商定除外); 4、在没有”无任何正当退款依据”的前提下,商品写有”一旦售出,概不支持退款”等类似的声明,视为无效声明; 5、在未拍下前,双方在QQ上所商定的交易内容,亦可成为纠纷评判依据(商定与描述冲突时,商定为准); 6、因聊天记录可作为纠纷评判依据,故双方联系时,只与对方在左子上所留的QQ、手机号沟通,以防对方不承认自我承诺。 7、虽然交易产生纠纷的几率很小,但一定要保留如聊天记录、手机短信等这样的重要信息,以防产生纠纷时便于左子介入快速处理。
查看详情

相关文章

猜你喜欢
发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务