• 两种同步机制:
      • 控制同步:例如,当一个任务的开始依赖于另一个任务的结束时,第二个任务不能再第一个任
        务 完成之前开始。
      • 数据访问同步:当两个或更多任务访问共享变量时,再任意时间里,只有一个任务可以访问该
        变量。
    • 原子操作和原子变量
      • 原子操作 :是一种发生在瞬间的操作。在并发应用程序中,可以通过一个临界段来实现原子操作,以便对整个操作采用同步机制。
      • 原子变量 :是一种通过原子操作来设置和获取其值的变量。可以使用某种同步机制来实现一个原子变量,或者也可以使用CAS以无锁方式来实现一个原子变量,而这种方式并不需要任何同步机制。
    • 线程之间通信方式
      • 共享内存 :通常用于在同一台计算机上运行多任务的情况。任务在读取和写入值的时候使用相同的内存区域。为了避免出现问题,对该共享内存的访问必须在一个由同步机制保护的临界段内完成。
      • 消息传递 :通常用于在不同计算机上运行多任务的情形。当一个任务需要与另一个任务通信时,它会发送一个遵循预定义协议的消息。如果发送方保持阻塞并等待响应,那么该通信就是同步的;如果发送方在发送消息后继续执行自己的流程,那么该通信就是异步的。
    • 死锁的四个条件
      • 互斥:资源不可共享
      • 占有并等待条件:一个任务既占有了资源,同时还要去请求别的资源
      • 不可剥夺:资源只能被那些持有它们的任务释放。
      • 循环等待:相互循环焦灼
    • 如何避免死锁
      • 忽略,遇到问题就重启
      • 检测机制,如果发现就强制释放某一个资源(数据库的事务关闭)
      • 预防:打断那四个条件
      • 规避:执行前先判断是否所有资源可以获取
    • 活锁

      如果系统中有两个任务,它们总是因对方的行为而改变自己的状态, 那么就出现了活锁。最终结果
      是它们陷入了状态变更的循环而无法继续向下执行 翻译就是:两人走路互相让路,同时左,同时右

    • JMM:Java内存模型

    操作系统:
    image.png
    image.png

    • 操作系统:因为存在CPU缓存一致性协议,例如MESI,多个CPU核心之间缓存不会出现不同步的问题,不会有“内存可见性”问题。
    • 重排序
      • 编译器重排序 :对于没有先后依赖关系的语句,编译器可以重新调整语句的执行顺序。
      • CPU指令重排序 :在指令级别,让没有依赖关系的多条指令并行。
      • CPU内存重排序 :CPU有自己的缓存,指令的执行顺序和写入主内存的顺序不完全一致。(“内存可见性”问题的主因 )
    • 内存屏障
      • 禁止编译器重排序和 CPU 重排序
      • 会用volatile就可以了,此外还有Unsafe里面的函数
    • as-if-serial
      • 不管怎么重排序(编译器和处理器为了提高并行度),(单线程)程序的执行结果不能被改变。
    • volatile

      • 单例模式的DCL(Double Checking Locking)
        1. public class Singleton {
        2. private static volatile Object instance; // 需要保证操作不重排序
        3. public static Singleton getInstance() {
        4. if (instance == null) {
        5. synchronized(Singleton.class) {
        6. if (instance == null) {
        7. // 此处代码有问题
        8. instance = new Singleton();
        9. }
        10. }
        11. }
        12. return instance;
        13. }
        14. }
    • happen-before的总结

      1.单线程中的每个操作,happen-before于该线程中任意后续操作。

      1. 对volatile变量的写,happen-before于后续对这个变量的读。
      2. 对synchronized的解锁,happen-before于后续对这个锁的加锁。
      3. 对final变量的写,happen-before于final域对象的读,happen-before于后续对final变量的读。