@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 访问操作数据的时间。

相关文章

一篇对伪共享、缓存行填充和CPU缓存讲的很透彻的文章

Java8使用@sun.misc.Contended避免伪共享

Java8的@sun.misc.Contended注解的更多相关文章

  1. Java8使用@sun.misc.Contended避免伪共享(False Sharing)

    伪共享(False Sharing) Java8中用sun.misc.Contended避免伪共享(false sharing) Java8使用@sun.misc.Contended避免伪共享

  2. sun.misc.BASE64Decoder 替代

    加密解密经常用到sun.misc.BASE64Decoder处理,编译时会提示: sun.misc.BASE64Decoder是内部专用 API, 可能会在未来发行版中删除 解决办法: Java8以后 ...

  3. sun.misc.BASE64Encoder找不到jar包的解决方法

    1.右键项目->属性->java bulid path->jre System Library->access rules->resolution选择accessible ...

  4. sun.misc.Unsafe的理解

    以下sun.misc.Unsafe源码和demo基于jdk1.7: 最近在看J.U.C里的源码,很多都用到了sun.misc.Unsafe这个类,一知半解,看起来总感觉有点不尽兴,所以打算对Unsaf ...

  5. Java--如何使用sun.misc.Unsafe完成compareAndSwapObject原子操作

    package com; import sun.misc.Unsafe; import java.lang.reflect.Field; /** * Created by yangyu on 16/1 ...

  6. MyEclipse中无法识别 sun.misc.BASE64Encoder

    sun.misc.BASE64Encoder/BASE64Decoder类不属于JDK标准库范畴,但在JDK中包含了该类,可以直接使用.但是在MyEclipse中直接使用却找不到该类. 解决方法: 1 ...

  7. Java sun.misc.Unsafe类的学习笔记

    Java未开源的Unsafe类 Unsafe类可以为我们提供高效并且线程安全方式操作变量,直接和内存数据打交道. 获取Unsafe实体的方法 private static Unsafe getUnsa ...

  8. sun.misc.BASE64Encoder和sun.misc.BASE64Encoder 找不到解决的方法

    1.右键项目->属性->java bulid path->jre System Library->access rules->resolution选择accessible ...

  9. MyEclipse/Eclipse导入sun.misc.BASE64Encoder jar包步骤

    1.右键项目 -->Properties -->Java Bulid Path-> Libraries -->JRE System Library-->Access ru ...

随机推荐

  1. 【线型DP】【LCS】洛谷P4303 [AHOI2006]基因匹配

    P4303 [AHOI2006]基因匹配 标签(空格分隔): 考试题 nt题 LCS优化 [题目] 卡卡昨天晚上做梦梦见他和可可来到了另外一个星球,这个星球上生物的DNA序列由无数种碱基排列而成(地球 ...

  2. MVC引用asp.net报表(测试小例子)

    public class Default1Controller : Controller { // // GET: /Default1/ public ActionResult Index() { r ...

  3. day38 作业

    实现并发的里两种方式 # 第一种 from multiprocessing import Process import time class MyProcess(Process): def run(s ...

  4. 使用 JS 开发 Github Actions 实现自动部署前后台项目到自己服务器

    不想看前面这么多废话的可以直接跳到具体实现 Github Actions 是什么? 说到 Github Actions 不得不提一下. 持续集成(continuous integration):高质量 ...

  5. 【Nginx】如何格式化日志并推送到远程服务器?看完原来很简单!!

    写在前面 Nginx作为最常用的反向代理和负载均衡服务器,被广泛的应用在众多互联网项目的前置服务中,很多互联网项目直接将Nginx服务器作为整个项目的流量入口.这就使得我们可以通过对Nginx服务器日 ...

  6. C#中的char和string的使用简介

    char 字符 char代表一个Unicode字符,它是System.Char的别名 char someChar = 'a';//定义了一个字符 char newLine= '\n';//这是一个换行 ...

  7. C# 判断和创建目录路径

    在进行一些导出或下载时,需要创建一个本地路径,以供文件进行下载和创建. if (Directory.Exists(Server.MapPath("~/upimg/hufu")) = ...

  8. Linux/Docker 中使用 System.Drawing.Common 踩坑小计

    前言 在项目迁移到 .net core 上面后,我们可以使用 System.Drawing.Common 组件来操作 Image,Bitmap 类型,实现生成验证码.二维码,图片操作等功能.Syste ...

  9. 检查string是否有重复尝试用map

    链接: 题意:输入一些单词,找出所有满足如下条件的单词:该单词不能通过字母重排,得到输入文本的另外一个单词.在判断是否满足条件时,字母不分大小写,但在输出时应保留输入的大小写,按字典序排列. 题解:先 ...

  10. MySQL(四)数据备份与还原

    数据备份与还原: 备份:将当前已有的数据或者记录保留 还原:将已经保留的数据恢复到对应的表中 为什么要做备份还原: 1.防止数据丢失:被盗.误操作 2.保护数据的记录 数据备份还原的方式很多:数据表备 ...