java 哈希表的内存图_java 的内存模型(Java Memory Model)

改变执行顺序

编译器、JVM 或者 CPU 共同努力通过改变执行顺序来最求程序的执行效率。

我们通常coding 时候,代码的执行是有一定顺序,这样保证我们可以完成一定逻辑,但是在 JVM 执行代码会根据需要,也就是最求性能来调整我们代码执行顺序。

但是这样调整顺序并不会影响程序执行的结果。

a = 3

b = 2

a = a + 1;

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

Load a

Set to 3

Store a

Load b

Set to 2

Store b

Load a

Set to 4

Store a

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

a = 3

a = a + 1

b = 2

Load a

Set to 3

set to 4

Store a

Load b

Set to 2

Store b

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

可见性

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

7181

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 进行读写操作。

7181

008.JPG

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

7181

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;

}

}

7181

010.JPG

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

7181

011.JPG

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值