Java之多线程内存可见性_2(synchronized可见性原理)

可见性:
要实现共享变量的可见性,必须保证2点:
1.线程修改后的共享变量值能够及时从工作内存刷新到主内存中。

2.其他线程能够及时把共享变量的最新值从主内存更新到自己的工作内存中。

以下的记录都是来源于慕课网-细说java多线程之内存可见性


Java语言层面你支持的可见性实现方式:(不包含jdk1.5之后的一些高级特性)
1.synchronized
2.volatile


synchronized 实现可见性
synchronized能够实现:
1.原子性(同步)
2.可见性

JMM关于synchronized的两条规定:
1.线程解锁前,必须把共享变量的最新值刷新到主内存中
2.线程加锁时,将清空工作内存中共享变量的值,从而使用共享变量时需要从主内存中
 重新读取最新的值(注意:加锁与解锁需要时同一把锁)
 
注:线程解锁前对共享变量的修改能在下次加锁时对其他线程可见


synchronized实现可见性
线程执行互斥代码的过程:

1.获得互斥锁
2.清空工作内存
3.从主内存拷贝变量的最新副本到工作内存
4.执行代码
5.将更改后的共享变量的值刷新到主内存
6.释放互斥锁


重排序
重排序:代码书写的顺序与实际执行的顺序不同,指令重排序是编译器或处理器为了提高程序性能
而做的优化


1.编译器优化的重排序(编译器优化)
2.指令级并行重排序(处理器优化)
3.内存系统的重排序(处理器优化)

如:可能会出现下面的结果
代码顺序:                             执行顺序
int number = 1;                   int result = 0;
int result = 0;                   int number = 1;


as-if -serial
as-if-serial:无论如何重排序,程序执行的结果应该与代码顺序执行的结果一致(Java编译器、
运行时和处理器都会保证java在单线程下遵循as-if-serial语义)

如:
    int num1 = 1;
int num2 = 2;
int sum = num1+num2;
单线程:第1、2行的循序可以重拍,但第三行不能
重排序不会给单线程带来内存可见性问题
多线程中程序交错执行时,重排序可能会造成内存可见性问题

你可能感兴趣的:(java)