Java8的@sun.misc.Contended注解
@sun.misc.Contended 介绍
@sun.misc.Contended 是 Java 8 新增的一个注解,对某字段加上该注解则表示该字段会单独占用一个缓存行(Cache Line)。
这里的缓存行是指 CPU 缓存(L1、L2、L3)的存储单元,常见的缓存行大小为 64 字节。
(注:JVM 添加 -XX:-RestrictContended 参数后 @sun.misc.Contended 注解才有效)
单独使用一个缓存行有什么作用——避免伪共享
为了提高读取速度,每个 CPU 有自己的缓存,CPU 读取数据后会存到自己的缓存里。而且为了节省空间,一个缓存行可能存储着多个变量,即伪共享。但是这对于共享变量,会造成性能问题:
当一个 CPU 要修改某共享变量 A 时会先锁定自己缓存里 A 所在的缓存行,并且把其他 CPU 缓存上相关的缓存行设置为无效。但如果被锁定或失效的缓存行里,还存储了其他不相干的变量 B,其他线程此时就访问不了 B,或者由于缓存行失效需要重新从内存中读取加载到缓存里,这就造成了开销。所以让共享变量 A 单独使用一个缓存行就不会影响到其他线程的访问。
Java 8 之前的方案
在 Java 8 之前,是通过代码里手动添加属性的方式解决的,如:
class LongWithPadding {
long value;
long p0, p1, p2, p3, p4, p5, p6;
}
一个 long 占 8 个字节,再添加 7 个 long 属性就会变成 64 个字节,刚好是一个缓存行大小。
但是注意,Java 7 开始 JVM 做优化时可能会把不用的变量给去掉,所以这种方法并不推荐使用。
适用场景
主要适用于频繁写的共享数据上。如果不是频繁写的数据,那么 CPU 缓存行被锁的几率就不多,所以没必要使用了,否则不仅占空间还会浪费 CPU 访问操作数据的时间。
相关文章
Java8使用@sun.misc.Contended避免伪共享
Java8的@sun.misc.Contended注解的更多相关文章
- Java8使用@sun.misc.Contended避免伪共享(False Sharing)
伪共享(False Sharing) Java8中用sun.misc.Contended避免伪共享(false sharing) Java8使用@sun.misc.Contended避免伪共享
- sun.misc.BASE64Decoder 替代
加密解密经常用到sun.misc.BASE64Decoder处理,编译时会提示: sun.misc.BASE64Decoder是内部专用 API, 可能会在未来发行版中删除 解决办法: Java8以后 ...
- sun.misc.BASE64Encoder找不到jar包的解决方法
1.右键项目->属性->java bulid path->jre System Library->access rules->resolution选择accessible ...
- sun.misc.Unsafe的理解
以下sun.misc.Unsafe源码和demo基于jdk1.7: 最近在看J.U.C里的源码,很多都用到了sun.misc.Unsafe这个类,一知半解,看起来总感觉有点不尽兴,所以打算对Unsaf ...
- Java--如何使用sun.misc.Unsafe完成compareAndSwapObject原子操作
package com; import sun.misc.Unsafe; import java.lang.reflect.Field; /** * Created by yangyu on 16/1 ...
- MyEclipse中无法识别 sun.misc.BASE64Encoder
sun.misc.BASE64Encoder/BASE64Decoder类不属于JDK标准库范畴,但在JDK中包含了该类,可以直接使用.但是在MyEclipse中直接使用却找不到该类. 解决方法: 1 ...
- Java sun.misc.Unsafe类的学习笔记
Java未开源的Unsafe类 Unsafe类可以为我们提供高效并且线程安全方式操作变量,直接和内存数据打交道. 获取Unsafe实体的方法 private static Unsafe getUnsa ...
- sun.misc.BASE64Encoder和sun.misc.BASE64Encoder 找不到解决的方法
1.右键项目->属性->java bulid path->jre System Library->access rules->resolution选择accessible ...
- MyEclipse/Eclipse导入sun.misc.BASE64Encoder jar包步骤
1.右键项目 -->Properties -->Java Bulid Path-> Libraries -->JRE System Library-->Access ru ...
随机推荐
- HDU - 5970 题解
题目链接 HDU - 5970 分析 很显然\(f(x,y)\)与\(f(x+y*k,y)\)的结果相同,因为它们在第一次取模后会变成相同的式子 我们再看一下数据的范围,突破口肯定在\(m\)那里 那 ...
- C++中复杂声明和定义的辨析
0x00 前言 c++中的复杂声明往往令人无法下手,经常使人搞错这到底声明的是一个指针还是指针函数.但其实c++对于复杂声明是遵循一定的规则的,叫做变量名—>右--左-右规则. 0x01 规则解 ...
- SimpleImputer 中fit和transform方法的简介
sklearn.impute.SimpleImputer 中fit和transform方法的简介 SimpleImputer 简介 通过SimpleImputer ,可以将现实数据中缺失的值通过同一列 ...
- element-ui 表单校验 Rules 配置 常用黑科技
type 指示type要使用的验证器.可识别的类型值为: string:类型必须为string.type 默认是 string // 校验 string: [ {type: 'string', mes ...
- element-ui(vue版)使用switch时change回调函数中的形参传值问题
需求说明 有多个switch组件 需要知道switch的状态 表格中当前行(scope.row)的数据 问题描述 官方文档中对switch中change的描述: 目前能得到switch的状态值,但是无 ...
- Drf06 /drf总结
Drf06 /drf总结 目录 Drf06 /drf总结 1. restful规范 2. drf组件认证的实现过程? 3. drf组件中权限的实现过程? 4. drf组件中节流的实现方式? 5. 什么 ...
- Python之爬虫(十五) Scrapy框架的命令行详解
这篇文章主要是对的scrapy命令行使用的一个介绍 创建爬虫项目 scrapy startproject 项目名例子如下: localhost:spider zhaofan$ scrapy start ...
- Go的100天之旅-01初识Go
初识Go Go简介 Go的历史 上个世纪70年代Ken Thompson和Dennis M. Ritchie合作发明了UNIX操作系统同时Dennis M. Ritchie发明了C语言. 2007年的 ...
- 计算机网络学习socket--day1
socket编程 socket可以看成是用户进程与内核网络协议栈的编程接口 socket不仅可以用于本机的进程间通信,还可以用于网络上不同主机的进程间通信 socket全双工通信 在异构系统间进行通信 ...
- python实现图片文字提取,准确率高达99%,强无敌!!!
上次我使用的百度AI开放平台的API接口实现图片的转化,后来有许多小伙伴都私信问我,怎么获取百度AI平台的AK和SK.为了统一回答大家的问题,今天我又使用百度API实现了一个从图片中提取文字和识别身份 ...