JVM复习(二)JMM内存模型1

简述:每个线程都有一个工作内存,它与主存独立,工作内存中存放主存变量的值的拷贝

  • 数据从主内存复制到工作内存时,有两个操作:

1、对主内存执行读操作read

2、对工作内存执行相应的装载load

  • 数据从工作内存拷贝到主内存时,有两个操作:

1、工作内存执行存储store

2、主内存执行相应的写操作write

线程通信要通过主存,JMM通过控制主内存与每个线程的本地内存之间的交互,来为程序提供内存可见性的保证

某线程修改了值,使用volatile可以让其他线程马上可见这个线程的改变

  • 保证可见性的方法(同步原语):

1、volatile;

2、synchronized(同步解锁前,会写变量值回主存而且同步操作会变成顺序执行);

3、final一旦初始化完成,其他线程就可知

  • 有序性概念:

1、在本线程内,操作都是有序的;

2、但是在线程外观察,对其他线程来说,操作又是无序的,因指令重排、主内存同步延迟等问题

3、指令重排:一个线程内,在不改变语义的情况下会改变各操作的执行顺序,但是多个线程的时候,编译器不会考虑多线程之间的语义。如:a=1;b=2;可重排,而a=2;b=a;有依赖的不可重排。

  • 保证有序性方法:synchronized

即使做了重排,因为互斥,其他线程看到这个线程也将是有序的,可以理解为,即使重排了,但是使用同步以后,等锁释放了才会看到结果,那么重排是没有影响的

  • 指令重排的原则:

1、程序顺序原则:一个线程内保证语义的串行性

2、volatile:happens-before原则,变量的写必发生于读

3、锁规则:happens-before原则,解锁unlock必发生于随后的加锁lock前

4、传递性:happens-before原则,A先于B,B先于C,那么A必然先于C

5、线程的start方法必先于它的每一个其他动作

6、线程的所有操作必先于线程的终结

7、线程的interrupt()先于被中断线程的代码

8、对象的构造函数执行结束先于finalize()方法

猜你喜欢

转载自blog.csdn.net/qq_37575994/article/details/102594121