缓存行 伪共享

public class LongAdder extends Striped64 implements Serializable {
    private static final long serialVersionUID = 7249069246863182397L;

    public LongAdder() {
    }

    public void add(long x) {
        Cell[] as; long b, v; int m; Cell a;
        // ...
    }

 

@sun.misc.Contended static final class Cell {
        volatile long value;
        Cell(long x) { value = x; }
        final boolean cas(long cmp, long val) {
            return UNSAFE.compareAndSwapLong(this, valueOffset, cmp, val);
        }
        // ...
}

ConcurrentHashMap中用Contended注解自动对CounterCell来进行填充:每个CounterCell记录了对应Node的键值对数目。这样每次计算size时累加各个CounterCell就可以了

ConcurrentHashMap中CounterCell以数组形式保存,而数组在内存中是连续存储的,CounterCell中只有一个long类型的value属性,这样CPU会缓存CounterCell临近的CounterCell,于是就形成了伪共享。

总结

  1. CPU缓存是以缓存行为单位进行操作的。产生伪共享问题的根源在于不同的核同时操作同一个缓存行。
  2. 可以通过填充来解决伪共享问题,Java8 中引入了@sun.misc.Contended注解来自动填充。
  3. 并不是所有的场景都需要解决伪共享问题,因为CPU缓存是有限的,填充会牺牲掉一部分缓存。

https://www.jianshu.com/p/a4358d39adac

https://www.cnblogs.com/cyfonly/p/5800758.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

beOkWithAnything

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值