并发基础

并发的根源

1源头之一:缓存导致的可见性问题

     一个线程对共享变量的修改,另外一个线程能够立刻看到,我们称为可见性

2源头之二:线程切换带来的原子性问题

把一个或者多个操作在 CPU 执行的过程中不被中断的特性称为原子性

3源头之三:编译优化带来的有序性问题

 

JVM 提供按需禁用缓存和编译优化的方法。包括 volatile、synchronized 和 final 三个关键字,以及六项 Happens-Before 规则

Volatile :禁用 CPU 缓存,告诉编译器,对这个变量的读写,不能使用 CPU 缓存,必须从内存中读取或者写入

Java 内存模型在 1.5 版本对 volatile 语义进行了增强:Happens-Before 规则。

Happens-Before 规则:前面一个操作的结果对后续操作是可见的

 

1. 程序的顺序性规则

 // 以下代码来源于【参考 1】

class VolatileExample {

  int x = 0;

  volatile boolean v = false;

  public void writer() {

    x = 42;

    v = true;

  }

  public void reader() {

    if (v == true) {

      // 这里 x 会是多少呢?   42

    }

  }

}

 

程序前面对某个变量的修改一定是对后续操作可见的

2. volatile 变量规则

  就是如果一个线程先去写一个volatile变量,然后一个线程去读这个变量,那么这个写操作的结果一定对读的这个线程可见

 

 

3.传递性

 

 

3 并发编程的 Bug 根源:

可见性、原子性、有序性

导致可见性的原因是缓存,导致有序性的原因是编译优化

4  需禁用缓存和编译优化的方法   volatile、synchronized 和 final   六项 Happens-Before 规则

 4.1  volatile 关键字并不是 Java 语言的特产,古老的 C 语言里也有,它最原始的意义就是禁用 CPU 缓存

我们声明一个 volatile 变量 volatile int x = 0,它表达的是:告诉编译器,对这个变量的读写,不能使用 CPU 缓存,必须从内存中读取或者写入

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值