我就站在你面前,你却视而不见!

在上一篇文章一男子给对象转账5000元,居然又退还了!中,我们学习了并发三大特性之一的原子性,并对原子性问题进行分析。

这篇文章我们就一起来了解下可见性:

可见性

首先看下可见性的概念:

可见性就是指某一个线程修改了共享变量的值时,其他线程能够立即得知这个修改

什么?难道变量被修改了,线程不应该马上读取到的吗?为什么和我认知的不一样呢?

好的,那么接下来让我们带着问题,一起来搞懂可见性问题。

可见性问题

可见性问题的元凶就是 CPU 缓存,都怪 CPU 为程序性能优化做的努力,搞出这么多幺蛾子。

关于 CPU 缓存可以阅读:原来 CPU 为程序性能优化做了这么多

首先在单核 CPU 上,是不存在可见性问题的,因为所有的线程都在一个 CPU 上执行,所有的线程都是操作同一 CPU 缓存,某一个线程修改了共享变量的值,另外的线程也可以马上读取到,因此是可见的。

如上图所示,Thread-0Thread-1 都是在一个 CPU 缓存上进行操作,所以 Thread-0 修改了变量 flag 的值后,Thread-1 再去访问变量 flag,得到的一定是最新的 flag 值。

然而在多核 CPU 上,由于每个 CPU 都有自己的缓存,当多个不同线程运行在不同的 CPU 上时,这些线程操作的 CPU 缓存也是不同的,因此某一个线程对共享变量进行修改时,另外的线程读取到的不一定是最新值,也就不具有可见性了。

多核CPU

如上图所示,Thread-0 是在 CPU-0 上的缓存进行操作,Thread-1 是在 CPU-1 上的缓存进行操作,所以 Thread-0 修改了变量 flag 的值后,Thread-1 再去访问变量 flag,得到的不一定是最新的 flag 值,因此 Thread-0 对共享变量 flag 的修改对 Thread-1 是不可见的。

下面用一个例子来看下可见性问题,创建一个 类,实现 接口,在 方法中判断 是否为 ,若为 则进行打印操作,主方法中启动一个线程 ,主线程等待

剩余60%内容,订阅专栏后可继续查看/也可单篇购买

后端核心技术精讲 文章被收录于专栏

专注分享后端技术干货,包括 Java 基础、Java 并发、JVM、Elasticsearch、Zookeeper、Nginx、微服务、消息队列、源码解析、数据库、设计模式、面经等,助你编程之路少走弯路。

全部评论
最好的关系就是互相成就,大家的订阅、点赞、收藏、留言四连就是我创作的最大动力。
点赞 回复 分享
发布于 2020-07-11 18:38

相关推荐

评论
1
收藏
分享
牛客网
牛客企业服务