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

【面试普通人VS高手系列】请简述一下伪共享的概念以及如何避免

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

【面试普通人VS高手系列】请简述一下伪共享的概念以及如何避免

一个工作5年的小伙伴,2个星期时间,去应聘了10多家公司,结果每次在技术面试环节,被技术原理难倒了。

他现在很尴尬, 简历投递出去就像石沉大海,基本没什么面试邀约。

技术能力的提升也不是一两天的事情,所以他现在特别焦虑。

于是,我从他遇到过的面试题里面抽出来一道,给大家分享一下。

“请简述一下伪共享的概念以及避免的方法”

对于这个问题,看看高手该怎么回答。

 部分高手面试文档已整理,需要的小伙伴可以扫描添加下方二维码

普通人:

额.................

高手:

对于这个问题,要从几个方面来回答。

首先,计算机工程师为了提高CPU的利用率,平衡CPU和内存之间的速度差异,在CPU里面设计了三级缓存。

CPU在向内存发起IO操作的时候,一次性会读取64个字节的数据作为一个缓存行,缓存到CPU的高速缓存里面。

在Java中一个long类型是8个字节,意味着一个缓存行可以存储8个long类型的变量。

这个设计是基于空间局部性原理来实现的,也就是说,如果一个存储器的位置被引用,那么将来它附近的位置也会被引用。

所以缓存行的设计对于CPU来说,可以有效的减少和内存的交互次数,从而避免了CPU的IO等待,以提升CPU的利用率。

正是因为这种缓存行的设计,导致如果多个线程修改同一个缓存行里面的多个独立变量的时候,基于缓存一致性协议,就会无意中影响了彼此的性能,这就是伪共享的问题。

像这样一种情况,CPU0上运行的线程想要更新变量X、CPU1上的线程想要更新变量Y,而X/Y/Z都在同一个缓存行里面。

每个线程都需要去竞争缓存行的所有权对变量做更新,基于缓存一致性协议。

一旦运行在某个CPU上的线程获得了所有权并执行了修改,就会导致其他CPU中的缓存行失效。

这就是伪共享问题的原理。

因为伪共享会问题导致缓存锁的竞争,所以在并发场景中的程序执行效率一定会收到较大的影响。

这个问题的解决办法有两个:

  1. 使用对齐填充,因为一个缓存行大小是64个字节,如果读取的目标数据小于64个字节,可以增加一些无意义的成员变量来填充。

  2. 在Java8里面,提供了@Contented注解,它也是通过缓存行填充来解决伪共享问题的,被@Contented注解声明的类或者字段,会被加载到独立的缓存行上。

已上就是我对这个问题的理解!

总结

在Netty里面,有大量用到对齐填充的方式来避免伪共享问题。

所以这并不是一个所谓超纲的问题,在我看来,多线程也好、数据结构算法也好、还是JVM,这是一个合格的Java程序员必须要掌握的基础。

我们习惯了在框架里面写代码,却忽略了各种成熟框架已经让Java程序员变得越来越普通。

本期的普通人VS高手面试系列就到这里结束了。

有任何不懂的技术面试题,欢迎随时私信我。

 部分高手面试文档已整理,需要的小伙伴可以扫描添加下方二维码

↓↓↓↓↓↓↓↓

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

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

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