java8 @Contented注解
阅读数:109 评论数:0
跳转到新版页面分类
python/Java
正文
一、概述
Java8引入了@Contented这个新的注解来减少伪共享(False Sharing)的发生。
二、伪共享
1、缓存行
CPU读取内存数据时并非一次只读一个字节,而是会读一段64字节长度的连续的内存块(chunks of memory),这些块我们称之为缓存行(Cache line)。
假设你有两个线程(Thread1和Thread2)都会修改同一个volatile变量x:
volatile long x;
如果Thread1先改变x的值,然后Thread2又去读它。
那么x所在缓存行上的所有64个字节的值都要被重新加载,因为CPU核心间交换数据是以缓存行为最小单位的。当然Thread1和Thread2是有可能在同一个核心上运行的,但我们此处假设两个线程在不同的核心上运行。
假设x所在缓存行里还有其他7个long型变量,v1到v7:x, v1, v2, v3, v4, v5 ,v6 ,v7。
2、不必要的数据共享
缓存行可以被许多线程访问。如果其中一个修改了v2,那么会导致Thread1和Thread2都会重新加载整个缓存行。这种不必要的数据共享就称之为“伪共享”(False Sharing)。
3、填充
减少伪共享其中一个手段就是通过填充(Padding)数据的形式,来保证本应有可能位于同一个缓存行的两个变量,在被多线程访问时必定位于不同的缓存行。
public class FalseSharingWithPadding {
public volatile long x;
public volatile long p2; // padding
public volatile long p3; // padding
public volatile long p4; // padding
public volatile long p5; // padding
public volatile long p6; // padding
public volatile long p7; // padding
public volatile long p8; // padding
public volatile long v1;
}
三、@Contended
除了对字段进行填充之外,还有一个比较清爽的方法,那就是对需要避免陷入伪共享的字段进行注解,这个注解暗示JVM应当将字段放入不同的缓存行,这也正是JEP142的相关内容。
该JEP引入了@Contented注解。被这个注解修饰的字段应当和其他的字段驻留在不同的位置。
public class Point {
int x;
@Contended
int y;
}
相关推荐
1、直接常量
为了编译器可以准确的知道要生成什么样的类型,可以给直接常量后面添加后缀字符标志它的类型,若为L表示long,F表示float,D表示double。也可以利用前缀表示进制,0x表示十六进制
一、类的继承
1、说明
(1)extends关键字用于类的继承。
(2)在C++中,方法的动态绑定是使用virtual关键字来实现的,而在Java中,动态绑定是默认的形为,不需要添加额外的关键字。
(
一、创建线程
创建线程有四种方式:继承Thread类、实现Runnable接口、实现Callable接口、通过线程池创建。
1、继承Thread
重写run方法。
class A extends Th
一、Collection接口
Collection接口的iterator和toArray方法都用于获得集合中的“所有元素”。前者返回一个“iterator”对象,后者返回一个包含集合中所有元素的数组。
1.hashCode的存在主要用于查找的快捷性,如hashtable,hastmap等,hashcode是用来在散列存储结构中确定对象的存储地址的。
2.如果两个对象相同,就是适用