1.2.1 同步/异步、阻塞/非阻塞式调用

  • 同步异步关注的是调用完成时消息的通知方式
    • 同步是调用方一直问询发现完成
    • 异步是一调用就立即返回,被调用方完成后会通知调用方已完成

第1章 走入并行世界 - 图1

  • 阻塞非阻塞关注的是发出请求到调用完成之间调用方的状态
    • 等待数据返回时设置为挂起态则为阻塞,不是挂起态则非阻塞

第1章 走入并行世界 - 图2

  • 举个例子:
    • 老张把水壶放到火上,立等水开。(同步阻塞)
    • 老张把水壶放到火上,去客厅看电视,时不时去厨房看看水开没有。(同步非阻塞)
    • 老张把响水壶放到火上,立等水开。(异步阻塞)
    • 老张把响水壶放到火上,去客厅看电视,水壶响之前不再去看它了,响了再去拿壶。(异步非阻塞)

1.2.2 并发和并行

  • 并发指的是多个进程宏观上同时进行,微观上交替进行
  • 并行是真的多个进程同时执行,只存在于多CPU的系统中,有几个CPU就能并行几个线程

1.2.3 临界区

  • 临界区是访问临界资源的代码段,每一次只能一个线程使用,其他线程等待

1.2.5 死锁、饥饿、活锁

  • 死锁:至少两个进程/线程一起死锁,都处于阻塞态
  • 饥饿:进程/线程一直无法获得资源,例如优先级太低一直排不到它

1.5 java内存模型(JMM)

  • 原子性:多线程执行时,每个线程执行完之前不能被其他线程干扰(例如在32位系统多线程写long数据)
  • 可见性:一个线程修改了共享变量的值,其他线程能否立即知道这个修改
  • 有序性:**在并发时,指令重排导致程序的执行可能就会出现乱序**

    拓展:

    第1章 走入并行世界 - 图3

  • 堆:运行时动态的分配内存大小,垃圾回收

  • 栈:存在栈中的数据可以共享,主要存放基本数据类型
  • 如图所示,如果两个线程同时调用了同一个对象Object3,都可以访问这个对象的成员变量,但是线程拥有的是对象的私有拷贝,保存在线程的本地内存中,然后再写回内存中,但是这样会出错,需要保证原子性可见性有序性,需要JMM
    • 第1章 走入并行世界 - 图4

1.5.4 Happen-Before规则

  1. 程序顺序原则:一个线程内根据代码顺序执行
  2. 锁原则:解锁(unlock)要在加锁(lock)之前

第1章 走入并行世界 - 图5

  1. volatile规则:volatile变量的写要在读之前,结合第四条传递性一起看
  2. 传递性:A先于B,B先于C,则A必然先于C

第1章 走入并行世界 - 图6
第1章 走入并行世界 - 图7

  1. start()原则:**主线程 A 启动子线程 B 后,子线程 B 能够看到主线程在启动子线程 B 前的操作**
  2. join()原则:线程 A 调用线程 B.join()让线程B插到A前面,那么线程B的任何操作都要先于A



**