并发和并行

并行:指在同一时刻,有多条指令在多个处理器上同时执行。
并发:指在同一时刻只能有一条指令执行。
并发编程三大核心问题:多线程同步,互斥,分工

并发三大特性

并发编程Bug的源头:可见性、原子性、有序性问题。
可见性:当一个线程修改了共享变量的值,其他线程可以看到修改的值。
原子性:一个或多个操作,要么全部执行并且不被打断,要么多不执行。
有序性:代码按先后顺序执行。

如何保证可见性:

  • 通过volatile关键字保证可见性。
  • 通过内存屏障保证可见性。
  • 通过synchronized关键字保证可见性。
  • 通过Lock保证可见性。
  • 通过final关键字保证可见性。

    如何保证原子性:

  • 通过synchronized关键字保证原子性。

  • 通过Lock保证原子性。
  • 通过CAS保证原子性。

    如何保证有序性:

  • 通过volitile关键字保证有序性。

  • 通过内存屏障保证有序性。
  • 通过synchronized关键字保证有序性。
  • 通过Lock保证有序性

volatile JVM内存屏障—>(汇编层面指令)lock;
lock前缀指令不是内存屏障的指令,但是有内存屏障的效果 缓存失效

Java内存模型(JMM)

规定了一个线程如何和何时可以可以看到其他线程修改过后的共享变量的值,以及在必须时如何同步共享变量。JMM是围绕原子性,有序性,可见性展开的。

Lock硬件层面扩展

指令寄存器取指令->查找寄存器->高速缓冲存储器->逻辑单元运算->回写到寄存器->回写到缓存->内存。
L1
L2
L3

缓存一致性的要求

  • 写传播
  • 事务串行化
  • 一致性机制

    MESI协议

    是一个基于写失效的缓存一致性协议,是支持回写缓存的最常用的协议。
    M:修改
    E:独占
    S:共享
    I:无效
    locl前缀指令 立即刷回主存
    总线锁定:串行 回到单核时代

    new对象过程

    1、开辟内存空间
    2、对象初始化
    3、指向内存空间的地址

    总结:

    Java中可见性是如何保证的?方式归类有两种:
    jvm层面storeLoad内存屏障 x86 ->lock替代了mfence
    上下文切换 Thread.yield();
    Java层面:vloatile,锁机制