Java内存模型

1.硬件的效率和一致性

 

   众所周知,处理器的运算速度和存储设备的运算效率相差几个数量级,处理器的运算速度比存储设备的运算效率高得多,为了缓解这种矛盾,Q1引入了高速缓存作为缓冲,但是这样还是有问题,什么问题呢?多个处理器都拥有自己的高速缓存,但它们又共享同一块主存,比如多个处理器操作了主存上的同一块数据,这个时候就有问题了到底谁是对的。这个时候又引入了Q2缓存一致性协议(具体有哪些可自行百度)。Q3处理器乱序执行代码,然后将结果重组保证结果正确性。类似的Java的内存访问方式和硬件的缓存访问操作很类似。相应的java即时编译器也有类似结果从组的指令重排序。

2.Java内存模型

 

   规则:

  • 所有的变量都存储在主内存中,每条线程还有自己的工作内存(可以与前面将的处理器的高速缓存类比),线程的工作内存中保存了该线程使用到的变量到主内存副本拷贝
  • 线程对变量的所有操作(读取、赋值)都必须在工作内存中进行,而不能直接读写主内存中的变量。
  • 不同线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要在主内存来完成。

3.Java内存间相互操作

  为了解决内存一致性,Java内存模型定义了8大操作来完成工作内存到主内存以及主内存到工作内存的内存操作,具体工作原理如下图:

 

 

 

 8大操作的使用原则:

  1、不允许read和load,store和write操作单独出现。(参照流程图很好理解,read和write,load和store是成对出现的)

  2、不允许一个线程丢弃它最近的assign操作,即变量在工作内存中的更新需要同步到主内存中。(待探求)

  3、不允许线程无原因地(没有发生过任何assign操作)把数据同步到主内存。(没有经过计算的数据是无意义的内存中本身就有)

  4、一个新的变量只能在主内存中产生,不能在工作内存中直接使用未被初始化的变量。

  5、一个变量在同一时刻只能被一个线程lock,并且lock和unlock需要成对出现。(为了线程安全)

  6、如果对一个变量执行lock操作,将会清空工作内存中此变量的值,在执行引擎使用这个变量前需要执行load或者assgin操作。(可能由于我的流程图不够完善,前半句是为了线程安全,后半句待探究)

  7、对一个变量执行unclock之前,必须把此变量同步到主内存中。(同样确保线程安全)

  初写博客作笔记用,不妥之处亟待修改完善,如有错误望大神指点!!!

posted @ 2021-04-27 18:00  silencelp  阅读(109)  评论(0)    收藏  举报