走进并行世界
本节是《Java高并发程序设计》第一章的读书笔记,为尊重原创,需要详细阅读的建议购买原著。
1.1 何去何从的并行计算
1.1.1 忘掉那该死的并行
并行计算一般只用在图像处理和服务端编程,需要引入多核计算,突破单核CPU算力的局限。
1.1.2 可怕的现实:摩尔定律的失效与发展
1、摩尔定律:英特尔创始人摩尔提出,大约每隔24个月(经常被引用为18个月),芯片的性能提升一倍。目前硬件发展到瓶颈,摩尔定律失效。因此,把更多的优化放在了软件层面,并行计算是一个重要的研究方向。
1.2 几个重要概念
1.2.1 同步和异步
1、简单理解,同步就是调用后需要等待返回的结果,才会继续执行下面的任务。异步则是调用,不会等待结果,而是转而继续执行下面的任务,等待回调函数通知再回来拿结果。
1.2.2 并发和并行
1、并发是多个任务交替执行,本质上还是串行,但是很多时候由于交替执行的时间很短,被认为是多个任务同时执行。
2、并行是多个任务同时执行。
1.2.3 临界区
1、临界区用来表示公共的资源或共享数据,可以被多个线程使用,但是每次使用仅能由一个线程,临界区被占用,其他线程需要等待。
1.2.4 阻塞和非阻塞
阻塞和非阻塞用来描述线程的相互影响。没有获得临界区资源的线程会被阻塞,非阻塞的线程会一直执行任务,不被影响。
1.2.5 死锁、饥饿和活锁
1、死锁是占有资源的线程不释放,且线程之间对资源的申请形成一个循环。
2、饥饿是线程因为种种原因无法获得资源,比如,线程优先级太低,导致资源持续被优先级高的线程获取。
3、活锁是线程间彼此“谦让“,主动将资源给对方,资源在两个线程间跳动,导致没有线程能拿到资源正常执行。
1.3 并发级别
将控制并发的策略分别阻塞、无饥饿、无障碍、无锁。
1.4 有关并行的两个重要定律
1、Amdahal定律和Gustafson定律
加速比:加速比 = 优化前系统耗时/优化后系统耗时
Amdahal定律关注CPU并行优化+串行化程序的比例,因此,仅提高CPU数量而不降低串行化比例,不一定满足系统性能提升。
Gustafson定律关注处理器的个数,主要不断累加处理器,就能获得理想性能。
二者不矛盾,极端情况都是一致。
1.5 回到Java:JMM
1、Java的内存模型(JMM)主要围绕原子性、可见性、有序性。
2、原子性:执行的动作不可被中断。
3、可见性:一个线程对共享变量操作后,其他线程能马上知道这个值。
4、有序性:程序的执行顺序和代码顺序不一定是一致的,由于编译优化和硬件优化等原因,会进行指令重排序,提高CPU的性能(原因是CPU需要流水化作业,调整汇编指令,能减少中断,提高CPU运行效率)
1.5.4 哪些指令不能重排序
1、一个线程内保证串行性。
2、volatile规则、锁规则、线程的中断(中断先于后续被中断代码)、对象的构造函数