写在前面
之前我们学习了JVM这本书,下面我们看一下关于高并发的这本书。书中一些概念我们在之前学习 java 进阶课程的时候已经接触过了。
在这本书中,我们期待可以对这些知识点做一下串联,形成一个知识网络。
这里参考 AmyZheng的笔记
第一章 走入并行的世界
这一章是基础内容,主要介绍一些基本概念和知识。

1. 基本概念
- 同步:一旦开始同步调用方法,调用者必须等到方法返回结果,才能继续后面操作
- 异步:异步调用方法,方法调用立即返回,调用者可以继续操作
同步和异步是针对方法调用而言的。
这里作者给了一个很形象的例子,买空调。如果去超市买,那就是同步调用;如果在网上下单,下单之后你可以做任何事情,等着送货上门即可,这就是异步调用。
- 并发(Concurrency):多个任务同时进行,偏重于任务交替进行,任务自身看还是串行的。
- 并行(Parallelism):真正的 同时进行。
这一对概念,在 JVM 中对于垃圾回收器的介绍中我们也涉及过。
- 临界区:一种公共资源或者说共享数据,可以被多个线程使用,但是一次只能一个线程使用
- 阻塞:等待其他线程释放资源。(之前说的阻塞等待,就是在等锁,锁就是一种资源)
- 死锁:都不让出资源
- 活锁:都让出资源。资源不断在两个线程之间跳动,但是实际上没有任何一个线程去使用资源。
- 饥饿:无法获取所需的资源。可能是由于线程的优先级太低,一直都有其他的线程占用资源,自己永远无法获取到资源。
2. 并发级别
由于有临界区,多线程之间的并发必须受到控制。这里并发的级别分为 阻塞、无饥饿、无障碍、无锁、无等待这么几种。
- 阻塞:线程是阻塞的,在获得资源之前,都无法执行。我们用 synchronized 和 重入锁,就是把线程设置为了阻塞线程。
- 无饥饿:对于非公平锁来说,线程调度倾向于高优先级的线程,有可能导致低线程出于饥饿状态。
真的不懂作者写在这里啥意思。就先按照公平锁和非公平锁来记吧。
- 无障碍:不加锁,多线程都进入临界区,共享数据出问题,回滚。
无障碍,
- 无锁:在无障碍的基础上,我们想要必然有一个线程能够在有限步骤内完成操作,离开临界区。书中给了一个compareAndSet() 方法的例子。
- 无等待:要求所有线程都必须在有限步骤内完成。典型的无等待结构就是RCU(Read-Copy-Update),读不控制,是wait-free无等待的,写只修改副本,在合适的时机写回数据。
就是说这里的读的无等待是有,后面的写副本 给 兜着的。
3. 两个重要定律
Amdahl定律:加速比 = 优化前系统耗时 / 优化后。
Gustafson定律:
这一部分先不看。很数学化的推导。
4. Java 的内存模型
- 原子性:
- 可见性:
- 有序性:在一个线程内看,操作都是有序的。但是在一个线程中观察另外的线程,操作都是无序的。前半句是指“线程内表现为串行语义”,后半句指“指令重排”和“工作内存与主内存的同步延迟”。
5. Happens-before 先行先发原则
- 程序顺序:线程内保证语义的串行性。
- Volatile规则:volatile变量先写,再读 (保证 volatile 变量的可见性)
- 锁规则:解锁在加锁之前,先 unlock,再 lock
- 线程启动规则:start() 在所有线程动作前
- 线程终止规则:线程所有操作在线程终止之前,Thread.join()
- 线程中断规则:线程中断优先于线程的代码
- 构造函数执行&结束 优先于 finalize() 方法
- 可传递性
网友评论