栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

多线程之伪共享

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

多线程之伪共享

伪共享 什么是伪共享

为了解决计算机系统中的内存与CPU之间运行速度差的问题,会在CPU和主内存之间添加一级或者多级高速缓冲存储器(Cache)。这个Cache一把是被集成到CPU内部的,所以也叫CPU Cache。

当多个线程同时修改一个缓存行里面的多个变量时,由于只能有一个线程操作缓存行,所以相比于每个变量放到一个缓存行,性能会有所下降,这就是伪共享。

为何会出现伪共享

​ 伪共享的原因是由于多个变量被放入一个缓存行中,并且多个线程同时去写入缓存行中不同的变量。因为缓存与内存交换数据的单位就是缓存行(利用程序运行的局部性原理加速程序运行)。

如何让避免伪共享

​ 在JDK 8之前都是通过字节填充的方式填充缓存行,避免多个变量占用一个缓存行。

public final static class FilledLong{
    public volatile long value = 0L;
    public Long p1,p2,p3,p4,p5,p6;
}

​ JDK 8提供了一个sun.misc.Contended注解,用来解决伪共享问题。

@sun.misc.Contended
public final static class FilledLong{
    public volatile long value = 0L;
}

​ 这里用来修饰类,也可以修饰变量,在Thread类中。

​ 在默认情况下,@Contended注解只用于Java核心类,比如rt包下的类。如果用户类路径下的类需要使用这个注解,则需要添加JVM参数:-XX:RestrictContended。填充的宽度默认为128,要自定义宽度可以设置为-XX:ContendedPaddingWidth参数。

小结

​ 讲述了伪共享是如何产生的,以及如何避免,并证明多线程访问同一个缓存的多个变量时才会出现,单线程访问一个缓存行的多个变量反而会加速(双层for中,访问array【i】【j】比访问array【j】【i】要快 )。为高级知识LongAdder的实现原理奠定基础。
(注:java并发编程之美)

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/361651.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号