Java多线程2.2-synchronized 实现原理

//阅读学习《Java并发编程的艺术》笔记,第二章

目录

synchronized 的应用

1-静态例子:类锁

2-非静态例子:对象锁

3-总结:(面试点)

Synchonized 在JVM 里的实现原理:

2.2.1 Java 对象头

2.2.2 锁的升级与对比(面试必面)


synchronized 的应用

synchronized修饰方法和代码块。(修饰变量会使变量既不能读也不能写)

锁住方法:是指不让拷贝该方法进行压栈操作了。只能有一个拷贝执行该方法,这个执行完下一个才能拷贝执行。

□ 对于普通同步方法,锁是当前实例对象。

□ 对于静态同步方法,锁是当前类的Class 对象。

□ 对于同步方法块,锁是Synchonized 括号里配置的对象。

1-静态例子:类锁

运行结果:线程1执行结束释放锁,线程2才能调用m3执行

示意图:因为是静态方法,所以m1在方法区

2-非静态例子:对象锁

运行结果:线程1执行结束,线程2才能执行。

示意图:静态方法在方法区,非静态方法伴随每个对象,都有一份。

3-总结:(面试点)

非静态的是对象锁,静态的是类锁;静态的加锁方法互斥;非静态的加锁方法互斥;不同类类型的不互斥

1、synchronized修饰静态方法-类锁

调用加锁的静态方法,锁住的是一个类。

其他的带锁的静态方法都不可以被调用。

静态方法只有一份,属于类,不管通过类还是对象,调用的都是那一份。

2、synchronized修饰非静态方法-对象锁

调用对象a加锁的非静态方法,锁住的是这个方法的对象,即对象a。

其他的对象a带锁的非静态方法都不可以被调用。

其他对象b、对象c不受影响。

3、synchronized修饰代码块

4、加锁和不加锁的方法调用互不干扰,对象锁和类锁互不干扰

凡是被synchronized修饰的方法,都必须排队使用


Synchonized 在JVM 里的实现原理:

JVM 基于进入和退出Monitor 对象来实现

代码块同步是使用monitorenter 和monitorexit 指令。

monitorenter 指令是在编译后插入到同步代码块的开始位置,而monitorexit 是插入到方法结束处和异常处, JVM 要保证每个monitorenter 必须有对应的monitorexit 与之配对。任何对象都有一个monitor 与之关联,当且一个monitor 被持有后,它将处千锁定状态。线程执行到monitorenter 指令时,将会尝试获取对象所对应的monitor 的所有权,即尝试获得对象的锁。

2.2.1 Java 对象头

Mark Word,对象头中用了32bit存储对象的hashCode 或锁信息等。

访问对象的时候去判断对象头锁标志位。

2.2.2 锁的升级与对比(面试必面)

偏向、轻量、重量说的是synchronized的三种状态。

无锁状态、偏向锁状态(可以设置为没有)、轻量级锁状态和重量级锁状态

这几个状态会随着竞争情况逐渐升级,锁可以升级但不能降级。

偏向锁:

场景:没有竞争,没有并发的情况下,比较快。

加锁过程简单,直接在对象头增加自己线程的ID;线程下次再次调用时,去查看对象头中的线程ID,如果是自己的,直接调用执行。

轻量级锁(自旋锁):

场景:最多两三个,小于5个的线程竞争。

在竞争少时,如果依靠等待通知才能来竞争是比较慢的,所以通过死循环自旋查看,这样速度很快,一释放就能感知到。

自旋锁能够在别的线程释放锁之后立马知道,然后去竞争。(反应快)

自旋只适用于少量线程低并发,在高并发情况下对CPU的开销太大了;因为一个线程持有锁,其余的线程都需要一直死循环访问,即占用CPU自旋。

重量级锁:

场景:两位数以上竞争。

所以在高并发情况下,轻量级锁需要升级为重量级锁。

竞争失败的线程进入阻塞队列,不额外消耗CPU,等待执行完的线程通知唤醒,再进入就绪队列竞争。

//没有并发偏向锁最快,低并发轻量级锁最快,高并发重量级锁最快。

//偏向锁用于无竞争情况下,轻量级锁个位数竞争,重量级锁两位数以上竞争。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值