继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

java 的内存模型(Java Memory Model)

青春有我
关注TA
已关注
手记 1239
粉丝 205
获赞 1008

改变执行顺序

编译器、JVM 或者 CPU 共同努力通过改变执行顺序来最求程序的执行效率。
我们通常coding 时候,代码的执行是有一定顺序,这样保证我们可以完成一定逻辑,但是在 JVM 执行代码会根据需要,也就是最求性能来调整我们代码执行顺序。
但是这样调整顺序并不会影响程序执行的结果。

a = 3
b = 2
a = a + 1;

这是上面代码的 JVM 执行的情况,我们加载 a 然后为 a 进行赋值,然后将其保存到内存中,同样操作在下两条语句。

Load aSet to 3Store a

Load bSet to 2Store b

Load aSet to 4Store a

我们发现执行过程中 load a 被执行了两次,我们需要对此进行优化。具体优化如下

a = 3
a = a + 1

b = 2
Load aSet to 3set to 4Store a

Load bSet to 2Store b

这些具体优化工作是 JVM 中完成的。

可见性

多线程的中一致性的表现,又叫做并发


webp

007.JPG

我们看最上面一层 core 这里表示有 4 个 cpu,每一个 cpu 都有一个 registers(注册机),然后就是 L1 cache 一级缓存,虽然不大因为 cpu 直接从这里读取内存所以这里非常快。然后就是 L2 二级缓存这里就是两个 core 来共享的。到了 3L 缓存就是所有 core 共享的内存区域。离 cpu 越远的缓存会访问速度降低同时容量变大。

public class FieldVisibility{  int x = 0;  public void writerThread(){
    x = 1
  }  public void readerThread(){    int r2 = x;
  }
}

这里创建一个 FieldVisibility 类,初始化 x = 0,让后提供两个方法分别在不同的线程对 x 进行读写操作。


webp

008.JPG

然后创建两个 FieldVisibility 的实例分别调用读和写方法来读写 x。

webp

009.JPG

当我们一个实例调用 writerThread 方法来修改 x 的值为 1,x = 1 仅会保存在 local cache 本地缓存,而不会更新到 shared cache (共享缓存),所以当另一个实例调用 readerThread 来获取 x 的值,依旧得到是 0 而不是 1.

这就是字段可见性问题。

public class FieldVisibility{  volatile int x = 0;  public void writerThread(){
    x = 1
  }  public void readerThread(){    int r2 = x;
  }
}

webp

010.JPG

当我们用关键字 volatile 修饰字段 x 时,当 x 发生变化会更新共享缓存,这样就保证 x 的更改对其他方法可见性。


webp



作者:zidea
链接:https://www.jianshu.com/p/5fcd7b2e7835


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP