Java高并发程序设计学习1:走入并行世界

  1. Linus认为并发应用场景: 图像处理,服务端程序
  2. 并行案例:淘宝双11
  3. 摩尔定律:18个月芯片性能提高一倍,指数增长,4GHz+接近理论极限,止步,定律失效。CPU数量增加,通过提升CPU内核数量提高性能,另一种摩尔定律。
  4. 硬件开发者无计可施,将摩尔定律的失效责任推脱给软件开发者。
  5. 同步,串行;异步,并行
  6. 并发:任务交替执行,而多个任务之间有可能还是串行的;并行,任务同时执行。
  7. 临界区:公共资源或共享数据,每次仅被一个线程占用,其他线程等待。
  8. 阻塞:一个线程占用资源,其他线程挂起,即阻塞;非阻塞,无线程占用,皆可访问。
  9. 死锁:线程不释放资源;饥饿,如线程优先级导致低优先级无法执行(插队);活锁,资源在两个线程之间跳动。
  10. 并发级别:阻塞,无饥饿,无障碍,无锁,无等待。
  11. 定律:
    Amdahl定律:
    加速比定义: 加速比 = 优化前系统耗时 / 优化后系统耗时
    说明:处理器再多,性能也是有上限的
    影响因素:CPU数量,串行化比重

Gustafson定律
加速比定义: 加速比 = 优化前系统耗时 / 优化后系统耗时
说明:不断累加处理器会获得更快的速度
影响因素:CPU数量

  1. 原子性:指一个操作不可中断。多线程一起执行,一个操作一旦开始就不会被打断。对于32位系统来说,long类型数据的读写不是原子性的,long有64位,会使多线程之间相互干扰。
  2. 可见性:
    说明:当一个线程修改某个值,其他线程是否知道这个修改。(串行必定知道,并行未必得知)
    导致原因:缓存优化或硬件优化,指令重排(汇编指令的重新排序),编辑器优化等
  3. Happen-Before规则
    说明:规定哪些指令不能重排,或重排必须遵守的规则。
    内容:

    程序顺序原则:一个线程内保证语义的串行性
    volatile规则:volatile变量的写,先发生于读,这保证了volatile变量的可见性
    锁规则:解锁必然发生在随后的加锁前
    传递性:A先于B,B先于C,那么A必然先于C
    线程的start()方法先于它的每一个动作
    线程的所有操作先于线程的终结
    线程的中断先于被中断线程的代码
    对象的构造函数执行,结束先于finalize()方法