并发编程读书笔记(二) volatile

Java 编译 后会 Java 节码 ,字 节码 器加 JVM 里, JVM 行字
,最 需要 为汇编 指令在 CPU 行, Java 中所使用的并 机制依 JVM 实现
CPU 的指令。
 

volatile的 synchronized

它在 理器 中保 了共享 量的 。可 性的意思是当一个 线
修改一个共享 ,另外一个 线 程能 个修改的 。如果 volatile 量修 符使用恰当
,它比 synchronized 的使用和 行成本更低,因 它不会引起线程上下文的切

 

汇编 指令来 volatile 进行写操作:0x01a3de1d: movb $0×0,0×1104800(%esi);0x01a3de24: lock addl $0×0,(%esp);
 
过查 IA-32 架构软 件开 者手册可知, Lock 的指令在多核 理器下会引 了两件事情
1)将当前理器存行的数据写回到系内存。
     Lock 指令 致在 行指令期 ,声言处 理器的 LOCK# 信号。
     ----Intel486 和Pentium处 理器,在 操作 是在 总线 上声言 LOCK# 信号。  锁总线开销比较大
     ----P6和目前的处理器中,如果访问的内存区域已经缓存在处理器内部,则 不会声言LOCK#信号。相反,它会锁定这块内存区
    域的 存并回写到内存,并使用 存一致性机制来确保修改的原子性,此操作被称 锁定 存一致性机制会阻止同修改由两个以上理器 存的内存区域数据
 
(老一代处理器锁总线,新一代处理器通过锁定内存地址,并使用缓存一致性保证修改的原子性)
 
!锁住总线,导致其他CPU不能访问总线,不能访问总线就意味着不能访问系统内存
 
2个写回内存的操作会使在其他CPU存了内存地址的数据无效。
嗅探一个 理器来检测 其他 理器打算写内存地址,而 个地址当前 于共享状 ,那么正在嗅探的
器将使它的 存行无效,在下次 访问 相同内存地址 存行填充。
(多核处理器中,一个处理器要改内存中的值,若“嗅探”到其他处理器打算(注意这个打算,是将要修改但还没改)写内存,则使他的缓存行无效,下次用的时候再强制填充缓存行 
 

volatile 在jdk1.7的优化

著名的 Java 发编 程大 Doug lea JDK 7 的并 包里新增一个 列集合 LinkedTransferQueue,它在使用 volatile ,用一种追加字 的方式来 列出 和入 的性能。

???追加字节是什么操作🤔

种方式看起来很神奇,但如果深入理解 理器架构就能理解其中的奥秘。让 先来看看 LinkedTransferQueue ,它使用一个内部 类类 型来定 义队 列的 头节点( head )和尾 点( tail ),而 个内部 PaddedAtomicReference 于父
AtomicReference 只做了一件事情,就是将共享 量追加到 64
可以来 算下,一个 对 象的引用占4 个字 ,它追加了 15 量(共占 60 个字 ),再加上父 value 量,一共 64 个 字节
什么追加 64 提高并 发编 程的效率呢 ?因 为对 于英特 酷睿 i7 、酷睿、 Atom
NetBurst ,以及 Core Solo Pentium M 理器的 L1 L2 L3 存的高速 存行是 64 个字 节宽 ,不
支持部分填充 存行, 意味着,如果 列的 头节 点和尾 点都不足 64 理器会将
到同一个高速 存行中,在多 理器下每个 理器都会 存同 、尾 点,当一
理器 试图 修改 头节 ,会将整个 存行 定,那么在 存一致性机制的作用下,会
其他 理器不能 访问 自己高速 存中的尾 点,而 列的入 和出 操作 需要不停修改 点和尾 点,所以在多 理器的情况下将会 重影响到 列的入 和出 效率。 Doug lea 使
用追加到 64 的方式来填 高速 冲区的 存行,避免 头节 点和尾 点加 到同一个
行,使 、尾 点在修改 不会互相 定。

 

简单来说,cpu 三级缓存L1 L2 L3  缓存行 宽度为64字节,若队列的字节不足,也会在锁定整个缓存行。如果填满64个字节,这样队列的头部和尾部不会分到同一缓存行,这样在一个cpu修改头部时,其他cpu中的缓存行只锁定头部所在缓存行,尾部操作不受影响。(虽然还是不能彻底理解,但是大概意思懂了 大师的操作果然高)

但也不是所有使用volatile的情况都会追加字节

1.缓存行字节宽不是64位的处理器  eg.奔腾 P6系列

2. 共享变量不会被繁地写。因使用追加字的方式需要理器取更多的字到高速 缓冲区,本身就会来一定的性能消耗,如果共享量不被繁写的的几率也非常小,就没必要通过追加字的方式来避免相互定。 不过这种追加字的方式在Java 7下可能不生效,因Java 7得更加智慧,它会淘汰或重新排列无用字段,需要使用其他追加字节的方式。

 

 

 

 

 

 
 
 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值