JDK1.8如何解决伪共享问题

Java8引入了@Contented这个新的注解来减少伪共享的发生。CPU在读取数据的时候并非一次读取一个字节,而是通过缓存行来进行读取。不同的CPU缓存行的长度并非一样,一般为64个字节长度。 比如有个数据类型内容如下:

public class MyNode {
	volatile MyNode head;
	volatile MyNode tail;
}

假设现在有两个线程A和B,线程A处理head头结点,线程B处理tail尾节点。理论上A线程和B线程修改不同的数据,之间应该不会有额外的影响。然而由于CPU加载数据的时候最小的额粒度为缓存行,比如当线程A来修改head会将锁住缓存行,将缓存的数据失效,这样在A线程修改的时候,那B线程只能等着A线程处理完,来获取最新的缓存行数据,这就发生了伪共享。伪共享也是并发编程里面隐藏的性能杀手。在1.8之前多数通过填充数据来解决。

public class MyNode {
	volatile MyNode head;
        volatile int a;
        volatile int b;
        .....
	volatile MyNode tail;
}

这样通过数据的填充,讲head和tail放在了不同的缓存行,这样就不会相互影响。在1.8就可以通过注解@Contended来解决这个问题。

import sun.misc.Contended;

public class MyNode {
	volatile MyNode head;
	@Contended
	volatile MyNode tail;
}

转载于:https://my.oschina.net/hongliangsun/blog/1614144

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值