前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并发编程进阶二:搞定可见性、有序性问题,用'它'就够了!!!

并发编程进阶二:搞定可见性、有序性问题,用'它'就够了!!!

作者头像
浩说编程
发布2021-08-17 17:28:23
3230
发布2021-08-17 17:28:23
举报
文章被收录于专栏:Java经验之谈Java经验之谈

承接上一篇"并发的三个潜在问题:CPU缓存引发的可见性、线程切换引发的原子性、编译优化引发的有序性"。

本篇就来探寻一下Java并发编程中针对"可见性、有序性"提供的解决方案。

上期回顾

并发编程进阶一:从“并发引发的潜在问题”开始

1

可见性:使用volatile禁用CPU缓存

我们在上一篇的分析中了解到,并发的可见性问题产生于各个CPU缓存中的数据副本与公共内存中的数据本体存在不一致的可能。

Java对于这个问题的解决思路是:提供关键字修饰的方式来主动的告知编译器“对于被修饰对象的处理,禁止使用CPU缓存,必须直接与内存交互”。

这样就避免了产生变量副本而与可见变量不一致的可能,这个关键字就是volatile

代码语言:javascript
复制
volatile int A = 0;

使用示例

2

有序性:Java内存模型的happens-before原则

什么是Java内存模型--Java Memory Model,JMM?

在了解happens-fefore原则之前需要先了解JMM,它可以理解成是一种虚拟机的规范,它规定了一个线程对共享变量的写入何时对另一个线程可见

从抽象的角度来看,JMM定义了线程和主内存之间的抽象关系:线程之间的共享变量存储在主内存(main memory)中,每个线程都有一个私有的本地内存(local memory),本地内存中存储了该线程以读/写共享变量的副本。

还记得这个图片吗,不管是在上一篇文章还是在前文中都有出现过,这种共享内存的并发模型就是一种JMM。

优化的JMM:happens-before原则

先看下面这段代码,假设现在有两个线程A和B,A 执行 writer() 方法,按照上文 volatile 语义,会把变量 “v=true” 直接写入内存。

假设线程 B 执行 reader() 方法,同样按照 volatile 语义,线程 B 会直接从内存中读取变量 v。

如果线程 B 看到 “v == true” 时,那么线程 B 看到的变量 x 是多少呢?

代码语言:javascript
复制
class VolatileExample {
  int x = 0;
  volatile boolean v = false;
  public void writer() {
    x = 1;
    v = true;
  }
  public void reader() {
    if (v == true) {
      System.out.println("x=" + x);
    }
  }
}

由于x我们并未使用volatile 修饰,CPU缓存和内存之间存在数据一致性问题,那么X的值0、1都有可能

于是从Java1.5开始,对JMM增加了happens-before原则来解决这个问题。

happens-before原则

1、程序的顺序性规则:一个线程中,按照程序顺序,前面的操作 Happens-Before 于后续的任意操作。

2、volatile域规则:对一个volatile域的写操作,happens-before于任意线程后续对这个volatile域的读操作

3、传递性规则:如果 A happens-before B,且 B happens-before C,那么A happens-before C。

通过这三条规则我们可以对上面的代码做这样的推断:

首先“x=42” Happens-Before 写变量 “v=true” --原则1

写变量“v=true” Happens-Before 读变量 “v=true” --原则2

“x=42” Happens-Before 读变量“v=true” --原则3

分析到这里我们可以得出一个结论:如果某个语句使用了volatile修饰,那么该语句之前所有代码的执行结果都对其他线程可见

所以从Java1.5开始,x的值一定是1,仔细体会一下,这就是happens-before的作用所在。

以上就是本篇的内容,总结一下涉及的知识点:volatile的作用、Java内存模型--JMM的概念、happens-before原则的作用。浩说编程,帮你学到更多!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-06-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 浩说编程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档