什么是伪共享(false sharing)
CPU缓存架构
伪共享
CPU缓存由缓存行组成,通常是 64 字节
(常用处理器的缓存行是 64 字节的,比较旧的处理器缓存行是 32 字节),并且它有效地引用主内存中的一块地址。
一个 Java 的 long 类型是 8 字节,因此在一个缓存行中可以存 8 个 long 类型的变量。
在程序运行的过程中,缓存每次更新都从主内存中加载连续的 64 个字节。因此,如果访问一个 long 类型的数组时,当数组中的一个值被加载到缓存中时,另外 7 个元素也会被加载到缓存中。
看起来似乎没有什么毛病,但是如果一个 CPU 核心的线程在对 a 进行修改,会导致在同一缓存行的a和b全部失效,如果这时有另一个线程要读取b,则需要重新从内存加载。
当多线程修改互相独立的变量时,如果这些变量共享同一个缓存行,就会无意中影响彼此的性能,这就是伪共享。
解决方式
1、在两个 long 类型的变量之间再加 7 个 long 类型
class Pointer {
volatile long x;
long p1, p2, p3, p4, p5, p6, p7;
volatile long y;
}
2、使用 @sun.misc.Contended 注解
默认使用这个注解是无效的,需要在JVM启动参数加上 -XX:-RestrictContended
才会生效
@sun.misc.Contended
class MyLong {
volatile long value;
}
Comments | 0 条评论