3. synchronized、CAS、volitale底层实现

synchronized、CAS、volitale底层实现

CAS

  1. Atomic类都使用CAS,它依赖于Unsafe类提供的compareAndSwap方法,如AtomicInteger依赖的是Unsafe的compareAndSwapInt方法,其是native的,实现在jvm源码unsafe.cpp中;

  2. unsafe.cpp中CompareAndSwapInt中是调用了Atomic::cmpxchg函数;

  3. 该函数在atomic_linux_x86_.inline.hpp中使用了汇编指令:

    使用了LOCK_IF_MP和cmpxchg

synchronized

  1. 编译时候:使用字节码monitorenter和monitorexit指令对实现;
  2. 运行时:JVM会对monitor做加锁优化,偏向锁-轻量级锁-重量级锁;
  3. lock 和cmpxchg汇编指令实现;

学会使用JOL

  1. 添加依赖:

     <dependency>
         <groupId>org.openjdk.jol</groupId>
         <artifactId>jol-core</artifactId>
         <version>0.9</version>
     </dependency>
    
  2. 使用ClassLayout:

     Object o = new Object();
     System.out.println(ClassLayout.parseInstance(o).toPrintable());
    
  3. 分析结果:

     java.lang.Object object internals:
      OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
           0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
           4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
           8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
          12     4        (loss due to the next object alignment)
     Instance size: 16 bytes
     Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
    

普通对象(x64):

  • 0~8字节:markword
  • 8~12字节:class pointer (启动了压缩指针)
  • 以后的都是:实例数据;
  • 以8字节为单位(64位处理器):填充,loss due to the next object alignment,因为对齐而丢失的字节;

数组对象在class pointer和实例数据之间还有4个字节,表示数组的长度;

对象头信息:

64位:

64bitObjectHeader.jpg

32位:


32bitObjectHeader.jpg

锁升级(具体加锁对对象头产生的影响,看上面的图):

  1. 对象new出来,第一次加锁,偏向锁;
  2. 竞争时,将升级为轻量级锁;
  3. 竞争比较大,多次重试无法获取到锁或者很多线程都在尝试获取同一个轻量级锁,将升级为重量级锁;

锁消除:

简单,仅仅放个标题;

锁粗话:

简单,仅仅放个标题;

hsdis插件可以查看jvm生成的汇编码:

启动时候指定参数,将打印生成的汇编码(需要暗转hsdis插件):

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly xxx; 

volitile:线程可见性、禁止重排序;

cpu超线程

内存中的数据要先加载到register中才能被cpu利用;

就是一个ALU单元 对应两组register和PC,这样省去了这两个线程之间切换时上下文切换的开销;

局部性原理:

当我们使用某个数据时,很有可能会使用相邻的数据;

cache line(64个字节)

cacheLine.jpg

缓存失效是以缓存行为单位的;

disruptor 环形队列,单机最快的队列,使用到了缓存行对齐,即让不同的volatile 变量存放在不同的缓存行中,提升效率;

MESI Cache一致性协议(X86 cpu):

每个缓存行有四种状态:

  1. Modified[图片上传中...(32bitObjectHeader.jpg-c9214c-1594222995296-0)]

  2. Exclusive

  3. Shared

  4. Invalid

跨越多个缓存行的数据,依然必须使用总线锁;

乱序执行:

int x,y,a,b;

new Thread(){
    run(){
        a=1;
        x=b;
    }
}.start();

new Thread(){
    run(){
        b=1;
        y=a;
    }
}.start();

如果没有乱序执行,那么x和y不会出现0和0的组合;

new 对象分几个步骤(加上指令重排序,所以DCL需要volatile)

  1. new 分配空间(这里的new类似于malloc);
  2. init方法(构造方法);
  3. astore_1();

volatile解决指令重排序

  1. 语言级别:volatile;

  2. 字节码:ACC_VOLATILE

  3. JVM:内存屏障,可以保证屏障前面的不会被重排序到后面去

    1. LoadLoad 屏障:屏障前Load操作和屏障后Load操作不能重排序,以下类似;

    2. StoreStore

    3. LoadStore

    4. StoreLoad

       //JVM保证volatile禁止指令重排序;
       StoreStoreBarrier
       volatile写操作;
       StoreLoadBarrier
      
       LoadLoadBarrier
       volatile读操作;
       LoadStoreBarrier
      
  4. hotspot:bytecodeinterpreter.cpp中实现:OrderAccess::fence();

  5. linux:orderaccess_linux_x86.inline.hpp还是lock实现的,没有指定对象,直接锁了总线;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,875评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,569评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,475评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,459评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,537评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,563评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,580评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,326评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,773评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,086评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,252评论 1 343
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,921评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,566评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,190评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,435评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,129评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,125评论 2 352