JDK 伪共享解决方案
关于AtomicReference
AtomicReference是由JAVA5引入的,用于对一个对象引用进行原子操作,我们可以看到AtomicReference的实现是用CAS技术对引用进行指令级别的原子修改,
然后再利用volatile带来的内存屏障特性, 保证引用的修改对其他线程立即可见。这里提一点,由volatile修饰的变量在写之后会插入一个store屏障,在读之前插入
一个load屏障。store屏障保证写操作被后面的线程立即可见。load屏障保证所有的读操作之前的写立即生效。然而AtomicReference并没有避免缓存行带来的缓
存命中率问题。一个AtomicReference对象包括一个volatile的对象引用,即这个对象在32位操作系统中占4个字节,在64位操作系统中占8个字节。虽然多个线程
对同一个AtomicReference对象操作没有并发问题,但是当多个线程对多个AtomicReference操作的时候就有可能有缓存命中率问题。借着上文中的模型我们假设
两个AtomicReference变量A和B位于同一内存相邻区域,当在核心1执行的线程对A变量操作的时候CPU会将A变量读入核心1的缓存区域,同时捎带把B变量读入缓
存区域,此时和A变量位于同一缓存行。核心2执行的另外一个线程同时对B进行操作,这个时候该缓存行已经失效,会发生一次读内存操作。
缓存行填充
Exchanger类是JAVA5提供的用于多线程之间交换数据的工具类,我们看看Exchanger的内部类Slot的实现:
private static final class Slot extends AtomicReference<Object> {
// Improve likelihood of isolation on <= 64 byte cache lines
long q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, qa, qb, qc, qd, qe;
}
Slot只是简单的继承了AtomicReference类,并声明了15个long类型的变量。如果不懂CacheLine的话不会明白这段无用变量的意义,这里声明了15个long类型的变量,
一个long类型为8个字节,加上上面的引用在64位操作系统环境下为128字节,32位操作系统环境下的124字节也没问题,因为两个Slot类型变量不可能位于同一缓存行,
这也就解决了多核CPU环境下的缓存航失效问题。
Disruptor的伪共享解决方案 http://www.cnblogs.com/yuyutianxia/p/6365959.html
EXchanger 解析: http://lixuanbin.iteye.com/blog/2166772
JDK 伪共享解决方案的更多相关文章
- Disruptor的伪共享解决方案
1.术语 术语 英文单词 描述 内存屏障 Memory Barriers 是一组处理器指令,用于实现对内存操作的顺序限制. In the Java Memory Model a volatile fi ...
- 关于java中的伪共享的认识和解决
在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素: CPU缓存 网页浏览器为了加快速度,会在本机存缓存以前浏览过 ...
- Java 中的伪共享详解及解决方案
1. 什么是伪共享 CPU 缓存系统中是以缓存行(cache line)为单位存储的.目前主流的 CPU Cache 的 Cache Line 大小都是 64 Bytes.在多线程情况下,如果需要修改 ...
- 伪共享 FalseSharing (CacheLine,MESI) 浅析以及Java里的解决方案
起因 在阅读百度的发号器 uid-generator 源码的过程中,发现了一段很奇怪的代码: /** * Represents a padded {@link AtomicLong} to preve ...
- 多线程中的volatile和伪共享
伪共享 false sharing,顾名思义,“伪共享”就是“其实不是共享”.那什么是“共享”?多CPU同时访问同一块内存区域就是“共享”,就会产生冲突,需要控制协议来协调访问.会引起“共享”的最 ...
- cache line 伪共享
https://blog.csdn.net/qq_27680317/article/details/78486220认识CPU Cache CPU Cache概述 随着CPU的频率不断提升,而内存的访 ...
- 伪共享(false sharing),并发编程无声的性能杀手
在并发编程过程中,我们大部分的焦点都放在如何控制共享变量的访问控制上(代码层面),但是很少人会关注系统硬件及 JVM 底层相关的影响因素.前段时间学习了一个牛X的高性能异步处理框架 Disruptor ...
- Java8的伪共享和缓存行填充--@Contended注释
在我的前一篇文章<伪共享和缓存行填充,从Java 6, Java 7 到Java 8>中, 我们演示了在Java 8中,可以采用@Contended在类级别上的注释,来进行缓存行填充.这样 ...
- 伪共享和缓存行填充,从Java 6, Java 7 到Java 8
关于伪共享的文章已经很多了,对于多线程编程来说,特别是多线程处理列表和数组的时候,要非常注意伪共享的问题.否则不仅无法发挥多线程的优势,还可能比单线程性能还差.随着JAVA版本的更新,再各个版本上减少 ...
随机推荐
- SVN 快速入门
一.SVN 简介 (1) SVN 是 Subversion 的缩写,是一个开源的版本控制系统(2) SVN 基于 C/S 架构,有一台中央服务器,多台客户端通过网络从中央服务器拉取或提交代码,以此达到 ...
- RAC的搭建(一)--安装环境准备
软硬件环境准备: 1.1 虚拟环境: VirtualBox上两个虚拟机,3G内存1核 1.2 软件环境: 数据库安装软件:p10404530_112030_LINUX_1of7.zip p10404 ...
- linux C 调用shell程序执行
#include<stdio.h> #include <unistd.h> #include <sys/types.h> #include <stdlib.h ...
- 2014 华为校招机试题(c/c++开发类)
第一题: 1.2.3....n盏灯,同时有n个人, 第1个人将1的倍数的灯拉一下, 第2个人将2的倍数的灯拉一下, ...... 问最后有几盏灯是亮的, 初始状态下灯是灭的, 输入整数n(n<6 ...
- Android与互联网的交互方式有三种
数据下载:下载网络上的的数据,包括图片.代码文本.XML文件.JSON数据,音/视频等大文件,调用webservice. 数据上传:上传图片.文本.XML.JSON数据.音/视频文件,调用webser ...
- win7 开机自启动控制
直接用win+r运行 --- 输入 msconfig 去除“OneNote”开机自启动方法:取消勾选,点击 “应用” ,然后点击“确定” 即可
- Android 缓存策略demo
packageinstaller\permission\model\PermissionApps.java /** * Class used to reduce the number of calls ...
- LeetCode 25 Reverse Nodes in k-Group Add to List (划分list为k组)
题目链接: https://leetcode.com/problems/reverse-nodes-in-k-group/?tab=Description Problem :将一个有序list划分 ...
- explain 和 desc 详解
MySQL性能分析 1.使用explain语句去查看分析结果 如explain select * from test1 where id=1;会出现:id selecttype table ty ...
- 使用 Gogs 搭建自己的 Git 服务器
安装过程分为这些步骤: 新建用户: 下载源码编译 / 下载预编译二进制打包: 运行安装: 配置调整: 配置 nginx 反向代理: 保持服务运行: 注意,这里默认你已经安装好了 MySQL 服务器和 ...