

Java并发知识梳理 - vcjmhg 的个人博客
source link: https://www.vcjmhg.top/how-to-learn-concurrency
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

随着摩尔定律逐步失效,CPU 单核性能达到瓶颈,并发逐渐逐渐得到广泛应用,因而学习了解以及使用并发就显得十分重要。但并发相关的知识比较琐碎,不易系统学习,因而本篇文章参照王宝令老师《Java 并发编程》来勾勒出一张“并发全景图”。
用学术定义来说就是
并发:同一时间段,多个任务都在执行 (单位时间内不一定同时执行);
简单来说就是,同一个时间段,让计算机同时做多个事情。
说到 并发
,不得不提就是 并行
:
并行:单位时间内,多个任务同时执行。
两者大眼一看很像,仔细一想却并不相同,因为 并行
强调某个时间点多个任务同时执行,而 并发
强调的是一个时间段内多个任务都在执行。
大部分并发问题,最终都可以抽象成三类问题分工、同步和互斥。而且针对不同的问题有着不同的方式来解决,具体如下图所示:
所谓 分工
,类似于现实中一个组织完成一个项目,项目经理要拆分任务,安排合适的成员去完成。
在并发编程领域,你就是项目经理,线程就是项目组成员。任务分解和分工对于项目成败非常关键,不过在并发领域里,分工更重要,它直接决定了并发程序的性能,并且分工非常重要且复杂,因而 Java 并发包中有一系列方法来实现 分工
:
- "Executor 与线程池"
- "ForkJoin"
- "Future 的使用"
基于分工思想设计的并发设计模式也有很多:
- "Guarded Supension 模式"
- "Balking 模式"
- "Threa-Per-Message 模式"
- "生产者-消费者模式"
- "Work Thread 模式"
- "两阶段终止模式"
而 同步
更多描述的是一种协同关系,在分完工之后,具体执行时,任务之间会有依赖,一个任务之后完成之后,其他依赖它的任务才能开始进行,因而就引入的 同步
来协同各个任务之间的执行顺序。
针对该类问题,Java 也提供了一系列工具来辅助解决:
- "信号量(Semaphore)机制"
- "管程(Monitor)"
- "CountDownLatch"
- "CyclicBarrier"
- "Phaser"
- "Exchanger"
分工、同步主要为了充分发掘 CPU 的性能来解决问题,但并发问题中,还需要解决正确性问题,即保证 线程安全
。
当多个线程同时访同一个变量时,最后执行的结果是不确定的,比如下边这段代码:
1public class UnsafeSequence {
2 private int value = 0;
3 public int getNext() {
4 return ++value;
5 }
6}
如果我们有多个线程同时调用 getNext()
时,多个线程之间推进顺序的不同可能会有不同的执行结果:
可能会是 2,递推顺序如下:
可能结果是 1,代码执行顺序如下:
因而结果是不确定的,也就是说结果可能是正确的(比如上边的程序执行结果为 2),可能是错误的(比如执行结果是 1),执行前是不知道的。而导致不确定的主要源头主要是三个问题可见性问题、有序性问题和原子性问题,为了解决这三个问题,Java 引入了内存模型,内存模型提供一系列规则利用这些规则,我们可以避免可见性问题、有序性问题,但是还不足以完全解决线程安全问题。解决线程安全问题的核心方案还是 互斥
。
所谓互斥,指的是同一时刻,只允许一个线程访问共享变量。
实现互斥主要手段是互斥锁主要包含下边这些手段:
- Synchronized
除此之外,未来提高速度,也有一些无锁的方案:
- 线程本地存储
- Copy - on - Write
本文主要从分工、同步和互斥三类问题展开,从解决对应问题角度出发大致梳理了 Java 并发知识的学习前景图。后续将分若干部分来讲对应的内容。
- 《深入理解 Java 虚拟机》
- 《Java 并发实战》
Recommend
-
5
前边我们讲了 sort 算法的原理,并且指出了它的不足--IDsw 过大,为了解决该问题,17 年时候 sort 算法的团队又提出了 DeepSort 算...
-
11
PCA降维以及维数的确定 - vcjmhg 的个人博客 2020-06-18 / 工具 ...
-
29
Github 作为程序员最大交友社区,想必每个程序员都不陌生。发起一个 PR 应该是无数 GitHub
-
9
vcjmhg 的个人博客 2020-04-29 / 操作系统 ...
-
5
2020-04-28 / java
-
9
2021-04-14 / java jv...
-
8
在 Java 语言中,Java 虚拟机只能理解 字节码(class文件),它不面向任何处理器,不与任何语言绑定,只与 Class文件 这种特定的二进制文件格式所关联。 Java 语言通过字节码的方式,在一定程度上解决了传统解释...
-
15
在之前的一篇文章《关于 java 继承的哪些事》简单讲了 Java 创建对象的过程,但具体细节当时并没有详细讲。因而本篇文章以 HotSpot 虚拟机为例,来讲一下 Java 虚拟机是如何创...
-
9
synchronized的原理及应用 - vcjmhg 的个人博客 2021-05-28 /
-
12
在大型项目中,在代码中直接创建线程是不允许的,如果需要使用多线性则必须通过线程池了创建,因而了解线程池的使用规范以及底层实现是非常有必要的。 预想的用法 但说到线程池,我们可能首先会类比连接池这类池化资源,会以为线程池是通过
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK