并发编程—锁

10 篇文章 1 订阅

操作系统

从操作系统层面看,有三种方式可以实现锁:pthread_mutex_lockspin信号量

Java层面

synchronized

在java中,synchronized可以用来做同步处理,一般的写法是synchronized(o){同步代码}。那么synchronized效率如何呢?
其实synchronized的效率是会发生变化的,它一般会从偏向锁->轻量锁->重量锁变化。

一般情况下,如果这个对象的是可偏向,那么对象第一次被线程持有的时候,锁状态是偏向锁。如果没有其他线程访问这把锁,而且当前线程再次加锁,那么这个对象的锁状态依然是偏向锁。
当有多个线程都交替访问这把锁时,锁的状态会膨胀为轻量锁。
一旦发生资源竞争,这个锁就会膨胀为重量锁。如果这个对象是不可偏向的,那么锁的状态会从轻量锁开始膨胀

随着锁的变化,效率会变得越来越低。当synchronized膨胀重量锁时,底层会使用pthread_mutex_lock实现互斥。
那么为什么使用了pthread_mutex_lock就会变成重量锁呢?
因为pthread_mutex_lock抢锁时,如果抢不到锁,会调用sleep指令,而sleep属于系统指令,当CPU处理RING3状态下时,没有权限执行sleep,这时,就需要升级到RING0,也就是CPU从用户态1升级到内核态2。而这是一个重量级操作,所以当使用pthread_mutex_lock实现锁时,就是重量锁了。

发生了系统调用的锁就是重量锁
比如sleep就属于系统调用,使用系统调用需要CPU从RING3升级到RING0

最优实践:
当我们在代码里写synchronized(o){}时,o一定不要调用super.hashCode()方法,就是object提供的那个native的hashCode()

在这里插入图片描述
ObjectL的hashCode返回222时,可以看到对象头中没有存储hashcode
在这里插入图片描述
当ObjectL的hashCode调用super.hashCode时,可以看到对象头发生了变化
在这里插入图片描述

对象头

锁的状态是存储在对象头中的。引申一下对象的组成:

  1. 对象头
  2. 实例数据(不一定有)
  3. 对齐填充(不一定有)

一个对象的大小一定是8byte的整数倍。对象头的大小一般是12byte,如果是一个空的Object,那么这个对象还会有4字节的对齐填充。对象头的12byte中,有8byte是markword,还有4byte的类型指针3当对象处于不同的状态时,8byte的markword中存的东西是不一样的。下面引用一下子路大神关于对象头存储内容的说明图片:
在这里插入图片描述
对象的hash值是存放在对象头中的,而且,一开始对象头中并没有hash值,当程序调用object.hashCode()时,才会计算hash值,然后存放在对象头中。当对象头中存放hash值后,就没有地方存储对象的偏向锁的线程id了。所以,如果一个对象的对象头中如果存储了hash值,那么就没空间存储偏向线程id了,这时,这个对象就不可偏向了,如果使用这个对象做锁,那么锁从一开始就是一个轻量锁。

synchronized的状态

synchronized的状态是会变化的,最优的情况下,会从偏向锁开始,逐步膨胀到轻量锁,最后膨胀为重量锁。最后,在极其苛刻的情况下,可以退化。synchronized的状态是存储在对象头中的。

自旋锁:

操作系统层面pthread_spin
reentrantlock 在jvm层面是自旋的,当高并发时,但是在os层面上不是,因为会park


  1. 用户态:运行用户程序 ↩︎

  2. 内核态:运行操作系统程序,操作硬件 ↩︎

  3. 类型指针:如果开启了指针压缩(默认开启),那么类型指针的大小就是4byte,如果没有开启,那就是8byte,也就是说,在没有指针压缩的情况下,对象头有16byte。-XX:-UseCompressedOops可以关闭指针压缩。 ↩︎

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值