【转帖】什么是内存可见性 什么是内存可见性

什么是内存可见性

 
https://www.cnblogs.com/powerjiajun/p/11564162.html

什么是内存可见性。。

感觉自己知道的还是非常少。。。 

什么是可见性?

一个线程修改了共享变量的值,其他线程也能看到最新修改的值 。

下图是一段存在线程可见性问题的代码:

111.png

在主线程中修改两个变量的值,不一定对副线程可见,副线程有可能读取到为false的ready和为111的num。

为什么会出现这样的结果?

线程的交叉执行,重排序加线程交叉执行,共享变量更新后的值没有在工作内存和主内存中及时更新。

首先要对java内存模型有一个大概的概念,每个线程有自己的工作内存,除此之外还有主内存区域,对变量的读写不一定会及时写入到主存,想要对其它线程可见,需要将工作内存中的写入同步到主存,并且同步到各个线程的工作内存中。

222.png

线程对共享变量的读写都必须在自己的工作内存中进行,而不能直接在主内存中读写。不同线程不能直接访问其他线程的工作内存中的变量,线程间变量值的传递需要主内存作为桥梁。

如何实现可见性?

在被synchronized保护的代码块中对共享变量进行写入,或者使用volatile修饰变量。

333.png

444.png

需要注意:Volatile通过内存屏障和禁止重排序来实现线程可见性。但不能保证原子性。

什么是可见性?

一个线程修改了共享变量的值,其他线程也能看到最新修改的值 。

下图是一段存在线程可见性问题的代码:

111.png

在主线程中修改两个变量的值,不一定对副线程可见,副线程有可能读取到为false的ready和为111的num。

为什么会出现这样的结果?

线程的交叉执行,重排序加线程交叉执行,共享变量更新后的值没有在工作内存和主内存中及时更新。

首先要对java内存模型有一个大概的概念,每个线程有自己的工作内存,除此之外还有主内存区域,对变量的读写不一定会及时写入到主存,想要对其它线程可见,需要将工作内存中的写入同步到主存,并且同步到各个线程的工作内存中。

222.png

线程对共享变量的读写都必须在自己的工作内存中进行,而不能直接在主内存中读写。不同线程不能直接访问其他线程的工作内存中的变量,线程间变量值的传递需要主内存作为桥梁。

如何实现可见性?

在被synchronized保护的代码块中对共享变量进行写入,或者使用volatile修饰变量。

333.png

444.png

需要注意:Volatile通过内存屏障和禁止重排序来实现线程可见性。但不能保证原子性。

猜你喜欢

转载自www.cnblogs.com/jinanxiaolaohu/p/12914655.html