并发编程|连小白都能听懂的“synchronized”关键字讲解,面试官直呼好!

相信大部分同学学过并发编程相关的课程都接触到了synchronized,它在并发编程中一直以元老级的角色存在,通过使用synchronized能够保证我们写的程序在多线程中能够按照我们的预期去执行,用过它的同学想必都知道这个关键字是很“笨重”的,非常消耗cpu资源,不过在jdk1.6中已经对它进行了优化,我们接下来开始学如何使用它以及jdk1.6中对他进行了哪些优化

synchronized 有哪几种使用方式?

  • 普通同步方法,锁是当前实例对象
  • 静态同步方法,锁是当前类的class对象
  • 同步代码块,锁事synchronized 括号中的对象
其中同步代码块是通过monitorenter和monitorexit进行实现,它们分别放在同步代码块开始和结束的位置,当然这个是编译器帮我们插入的。

jvm 怎么标识线程已经获取锁呢?这得要说说java对象头了

存储对象的hashcode或锁信息存储到对象类型数据的指针数组长度(如果当前对象是数组)
Mark WordClass Metadata AddressArray length
上面就是对象头的基本结构了,锁的状态也是存储在Mark Word中,在jdk1.6中,为了减少synchronized 获得锁和释放锁带来的性能消耗,Mark Word中锁的状态由`无锁状态``偏向锁``轻量级锁``重量级锁`组成,锁的等级一级比一级高。

注意:锁可以升级但是不能降级

什么是偏向锁?

hotspot作者研究发现,锁在大多数情况下不存在竞争,并且总是被同一个线程获取,为了让线程获得锁的代价更低,于是引入了偏向锁:当一个线程获取锁并且进入了同步代码块之后,会在当前的锁对象头中记录当前线程的线程Id,后续再次进入代码块时,只需要判断锁对象头中的线程ID是否是自己,如果是的话则不再需要进行Cas加锁和解锁,否则需要重新获取。
  • 偏向锁的获取

    1. 线程A进入临界点前,判断对象头中Mark Word中是否存着指向本线程的偏向锁,如果有,则直接获取锁成功,进入临界区,如果不存在,则执行下一步
    2. Mark word的偏向锁表示位是否设置成1(当前已经是偏向锁),如果没有,则使用CAS竞争锁,否则
    3. 使用CAS将对象头的偏向锁指向当前线程
  • 偏向锁的撤销

    1. 锁撤销只会发生在锁竞争的时候并且当前没有正在执行的字节码
    2. 暂停拥有偏向锁的线程
    3. 检查拥有偏向锁的进程是否存活,如果不处于存活状态,则将对象头设置为无锁状态,否则
    4. 如果线程一直存活,则拥有偏向锁的栈会被执行,栈中的锁记录和对象头的Mark word要么重新偏向于其他线程,要么恢复到无无锁状态,最后唤醒暂停的线程
  • 关闭偏向锁
    偏向锁在jdk中默认是启用的,如果你确定你的线程中会发生锁竞争,那么你可以使用如下命令关闭偏向锁
    -XX:BiasedLockingStartupDelay = 0;

轻量级锁

  • 轻量级锁加锁

    1. 线程在执行同步代码块之前,JVM会在当前的栈桢中创建存储锁记录的空间,并将锁对象头的Mark Word内容复制到刚才创建的锁记录空间中,这一步叫做“Displaced Mark Word”,
    2. 然后当前线程尝试使用CAS将对象头中的Mark Word替换为指向当前锁记录空间的内存地址,
    3. 如果替换成功则成功获取锁,否则表示有其他线程在竞争这把锁,则
    4. 使用自旋的方式来获取锁。
  • 轻量级锁解锁

    1. 使用CAS操作将获取锁之前复制的Mark Word替换回锁对象头中,如果成果成功,则表示没有竞争发生,
    2. 如果失败,锁就会膨胀成重量级锁,并且在使用自旋方式尝试获取轻量级锁的线程会被阻塞
    3. 拥有轻量级锁的线程释放锁并唤醒等待的线程,被唤醒的线程重新争夺锁,访问临界区。

为什么锁不能被降级

因为自旋锁会消耗CPU,为了避免无用的自旋操作,特别是当持有锁的线程被阻塞了,一旦锁升级为重量级锁,就不会再恢复到轻量级锁,当锁处于这个状态下,其他线程试图获取锁时,都会被阻塞住,当持有锁的线程释放锁之后,会唤醒这个阻塞的线程,被唤醒的线程重新争夺锁。

锁的优缺点对比

优点缺点使用场景
偏向锁加锁和解锁不需要额外的消耗如果线程间存在竞争,则需要额外消耗只有一个线程的场景
轻量级锁竞争的线程不会阻塞,提高程序响应速度自旋操作,时间过长会消耗过多的cpu追求响应时间,同步块中的任务执行的很快,不会长时间阻塞
重量级锁线程竞争不使用自旋,不会消耗过多cpu线程阻塞,响应时间慢追求吞吐量,同步块执行时间长

在这里插入图片描述

微信搜一搜【AI码师】关注帅气的我,回复【干货】,将会有大量面试资料和架构师必看书籍等你挑选,包括java基础、java并发、微服务、中间件等更多资料等你来取哦。
书读的越多而不加思考,你就会觉得你知道得很多;而当你读书而思考得越多的时候,你就会越清楚地看到,你知道得很少。——伏尔泰

评论 24
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

乐哥聊编程

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值