下面会介绍到volatile关键字,java内存模型,并发编程中的三个特性(原子性,可见性,有序性),happen-beforeg规则
-
java内存模型
线程之间的共享变量存储在主内存中,每个线程都有一个私有的本地内存,本地内存中存储了该线程以读/写共享变量的副本。
当需要两个线程去通信时,例如A线程把本地内存中的的共享变量更新之后刷新到主内存中,然后B线程去主内存中读取A线程更新后的资源。这也是造成了线程不安全的主要原因。
缓存一致性协议:
MESI是一种主流的缓存一致性协议,已经用在Pentium和PowerPC处理器中。它定义了缓存块的几种状态
● modified(修改):缓存块已经被修改,必须被写回主存,其他处理器不能再缓存这个块
● exclusive(互斥):缓存块还没有被修改,且其他处理器不能装入这个缓存块
● share(共享):缓存块未被修改,且其他处理器可以装入这个缓存块
● invalid(无效):缓存块中的数据无效
核心思想:
1.当cpu写入数据时,如果发现当前数据是共享数据(也就是说其它cup中也存中这个数据的副本),会 发出一个信号通知其他cpu该变量的缓存无效
2.当其他cpu访问该变量时,会重新导主内存中去获取。Volatile关键字
1.保证重排序的是偶不会把后面的指令放到屏障的前面,也不会把前面的放到后面
2.强制对缓存的修改操作立刻写入主存
3.如果是写操作,他会导致其他CPU中的缓存失效三个特性
1.原子性
一个操作或者多个操作,要么都成功,要么都失败,中间不能由于任何因素中断。2.可见性
指的是一个线程修改了某个共享变量后,其它的线程能立刻得知这个修改后的值。3.有序性
重排序只保证最终一致性。happen-beforeg原则
1.代码的执行顺序,编写在前面的发生在编写在后面的
2.unlock必须发生在lock之后
3.volatile修饰的变量,对一个变量的写操作先于对该变量的读操作
4.传递规则:A先于B,B先于C,那么A肯定先于C
5.线程的启动规则:start方法肯定先于线程run方法;
6.线程的中断规则:interrupt这个动作,必须发生在捕获动作之前
7.对象销毁规则:初始化必须发生在finalize之前
8.线程的终结规则:所有的操作都发生在线程死亡之前