Java 并发编程学习笔记
1
Java 并发编程学习笔记
高阶圣堂武士
前言
人们一直认为并发编程技术是 Java 编程中的高级技术,没有必要掌握。由
于一些技术框架提供了较好的多线程支持(比如 Servlet、RMI), 很多时候软件
工程师可以不必过多考虑多线程问题。然而,如果你是一个大型数据分析/数据
挖掘软件的架构师的话,你就需要使用并发技术来提供高吞吐量、高可伸缩性和
快速响应能力,因为这些特性是一个设计良好的商业软件必须具备的,而技术框
架提供的线程隔离已经不能满足这方面的需要。
通过使用并发技术可以开发出并行算法,充分利用多处理器系统的计算能
力,提高任务执行速度。此外,很多软件中存在的时隐时现的 Bug 都是由于开发
人员不懂并发造成的,这种 Bug 通常难以发现和修复,导致软件的维护成本很高。
因此对于 Java 高级程序员来说,并发编程已成为一项必备的技能。
目前,在 Java 并发编程方面论述系统、内容详实的中文资料很少。本文是
作者在实际工作中经验总结,有一部分内容来自《Java Concurrency In
Practice》。如果英文较好的话,建议还是看《Java Concurrency In Practice》
毕竟本文作者的水平有限。你需要具备 Java 核心编程基础知识才能够看懂本文
中的大部分内容,因而并不鼓励编码量较少的初级 Java 程序员阅读。一般来说,
读完前八章即可应付一般的 Java 多线程应用程序。
本文仅供编程爱好者学习交流之用,请下载后 24 小时内删除。请不要将本
文用于任何商业目的,否则后果自负。
Java 并发编程学习笔记
1
目 录
第一章 概述 ..................................................................................................................................... 7
1.1. 并发简史 ......................................................................................................................... 7
1.2. 使用多线程的好处 ......................................................................................................... 8
1.2.1. 利用多处理器的处理能力 ................................................................................. 9
1.2.2. 建模的简单性 ..................................................................................................... 9
1.2.3. 简化异步事件的处理 ....................................................................................... 10
1.2.4.更好的用户界面响应能力 ................................................................................. 10
1.3. 使用多线程的风险 ....................................................................................................... 11
1.3.1. 安全风险 ........................................................................................................... 11
1.3.2. 活跃性风险 ....................................................................................................... 13
1.3.3. 性能风险 ........................................................................................................... 13
1.4. 多线程无处不在 ........................................................................................................... 14
第二章 线程安全性 ....................................................................................................................... 16
2.1. 什么是线程安全 ........................................................................................................... 17
2.1.1. 一个无状态的 Servlet .................................................................................... 18
2.2. 原子性 ........................................................................................................................... 19
2.2.1. 竞争条件 ........................................................................................................... 20
2.2.2. 延迟初始化 ....................................................................................................... 20
2.2.3. 复合操作 ........................................................................................................... 21
2.3. 锁 ................................................................................................................................... 22
2.3.1. 内部锁 ............................................................................................................... 23
2.3.2. 重入 ................................................................................................................... 24
2.4. 使用锁确保对象状态一致性 ....................................................................................... 25
2.5. 活跃性和性能 ............................................................................................................... 26
第三章 共享对象 ........................................................................................................................... 30
3.1. 内存可见性 ................................................................................................................... 30
3.1.1. 陈旧数据 ........................................................................................................... 31
3.1.2. 非原子性 64 位操作 ......................................................................................... 32
3.1.3. 锁和可见性 ....................................................................................................... 33
3.1.4. volatile 域 ...................................................................................................... 33
3.2. 发表与逃逸 ................................................................................................................... 34
3.2.1. 安全构造实践 ................................................................................................... 36
3.3. 线程封闭 ....................................................................................................................... 37
3.3.1. Ad-hoc 线程封闭 .............................................................................................. 38
3.3.2. 堆栈线程封闭 ................................................................................................... 38
3.3.3. ThreadLocal ..................................................................................................... 39
3.4. 不可变对象 ................................................................................................................... 40
3.4.1. final 域 ............................................................................................................ 41
3.4.2. 使用 Volatile 来发表 Immutable 对象 ......................................................... 42
3.5. 安全发表对象 ............................................................................................................... 43
3.5.1. 不合理的对象发表方式 ................................................................................... 44
3.5.2. Immutable 对象和初始化安全 ........................................................................ 44