并发编程学习笔记3

并发编程之synchronized同步

1.java级别的知识-synchronized

1.1 k=k+1这条指令

  • java意义上是一行代码,两条指令,得到的汇编代码.o文件,然后再反汇编成可以看懂的机器码就更多了

  • t1线程执行时只做完k+1,当t2线程来时,此时k还是原值,所以两个线程执行,最后的结果只进行了1次加法

  • caslock.lock();

2.caslock

  • volatile status = 0;

    unsafe.compareAndSwapInt(this,valueOffset,expect,newVal);(cpu原语,一条机器指令)

  • void lock(){

    ​ while(!compareandswap(0(expect),1(new val))){

    ​ //空方法

    }

    }

  • void unlock(){

    ​ status = 0;

    }

3.锁的语意

  • 锁,对象当中的一个标识

  • 加锁:就是去改变这个对象的标识的值

  • 加锁成功:让方法正常返回

  • 加锁失败:让失败的这个线程死循环 (cas) 或者阻塞(sleep)

4.synchronized怎么实现锁

  • 业内一般叫做锁对象(从结果)

  • synchronized究竟改变了对象的什么?

    • 对象头

      • 怎么看对象布局

        • 对象多大–8的倍数字节(添加一个依赖jol-core,里面有个对象classLayout.parseInstance().toPrintable())

        • 具体的内容

          • type
          • GC state
            • 分代年龄
            • 是否被gc标记
          • synchronized state:是否加了synchronized关键字
          • identity hash code:
        • 上面整体又可以看出由两部分组成

          • 第一部分mark word(8byte)

            • 没有使用
            • 偏向标识
            • 偏向时间戳

            1.存了hashcode(小端存储)-- 高字节存储高地址,低字节存低地址,有点像入栈的过程,所以取出来就变成倒序了。

            2.前25位标识是标识是否使用的

            3.前提一定要hash计算了

            4.1 第一种状态是无锁不可偏向有hash状态

            ​ 第二种状态是无锁可偏向无hash状态

            5.1 锁的重量程度,任何对象初始化都是01,但, 偏向锁(01) -》轻量锁(00) -》 重量锁(10)(锁的膨胀过程)

            5.2 当一把锁第一次被线程持有的时候是偏向锁,如果这个线程再次加锁还是偏向锁,如果别的线程来加锁(交替执行),膨胀为轻量锁,如果是资源竞争膨胀成重量锁

            6.gc标记(),也是在上述锁的重量程度里面表示

            7.计算了hash 00000001 - 》 001 当前对象锁状态是偏向锁,但是不能偏向(三位中的首位)

            不计算hash 00000101

            8.偏向延迟 -XX:+biaslockdelay…(需要修正)

            1. 计算了hashcode,地址里面就存不了线程id,所以hashcode和偏向是互斥的,
            2. 当一把锁第一次被线程持有的时候,前提是没有计算hashcode,并且是偏向锁被打开的程度下,是偏向锁,如果这个线程再次加锁还是偏向锁,如果别的线程来加锁,交替执行(有join,资源已经释放),是轻量锁,如果有资源竞争(同时获取锁,t1持有锁,但是t1没释放,t2获取不到锁,此时两者的锁标识都是重量锁),是重量锁
          • 第二部分klass pointer(4 byte)

            • 把类编译后的class文件存储地址的首地址(用指针表示),指向类的模板
            • 长度有可能是4,有可能是8(看是否开启指针压缩)
    • 实例数据

    • 对齐填充

  • 偏向锁效率高

    • 首先判断是否可偏向,发现锁可偏向,则去拿到当前线程的id,通过cas设置到对象头,

2.操作系统知识补充

2.1 虚拟地址映射

  • 要说明虚拟地址,需要说清进程,

  • 代码块、数据块、堆、栈

  • gcc -g -c xx.c

  • Objdump -s xx.o

    可以看到汇编代码

    &l 打印出来的是虚拟地址,是假的

  • gcc -c xx.c xx.out

  • ./xx.out

    cat /proc/进程号/maps,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值