Synchronized锁

为何要设计锁:

多线程编程中,多个线程同时访问同一个共享可变资源,并发访问会导致线程安全问题,锁用来保证线程安全。

在这里插入图片描述

内存模型

在这里插入图片描述

原子操作

在这里插入图片描述

Synchronize锁

不加锁:不能保证代码段的原子性

加锁:保证代码段逻辑的原子性。序列化访问临界资源,同一时刻只能有一个线程访问临界资源(同步互斥访问)

锁定义:

  • 显示锁:reentrantLock,ReentrantReadWriteLock,手动加锁与解锁
  • 隐式锁:JVM内置锁,不需要手动加锁与解锁
synchronized(object){

}

加了锁之后,字节码多了monitorenter ,monitorexit

monitorenter 进入

代码逻辑

monitorexit退出

加锁:

  • 同步实例方法:锁是当前实例对象
  • 同步类方法:锁是当前类对象
  • 同步代码块:锁是括号里的对象

原理:

JVM内置锁通过synchronized使用,通过内部对象Monitor(监视器锁)实现,基于进入与退出Monitor对象实现方法与代码块同步,监视器锁的实现依赖底层操作系统的Mutex Lock(互斥锁,原理:互斥量)实现。是重量级锁,性能较低。

只有一个线程可以拿到Mutex 互斥量,进入代码段,没有抢到锁的线程,进入waitSet

java1.4以前,申请互斥量时,需要从用户态切换到内核态,悲观锁

在这里插入图片描述

T1释放锁后,通知同步队列唤醒阻塞的线程,队列里的线程进入entryList,再次竞争。

JVM内置锁是否可以手动控制加锁与解锁?jdk1.8可以

unsafe类

方法 monitorEnter(Object varl), monitorExit(Object varl)

只能通过反射获取

UnsafeInstance.reflectGetUnsafe().monitorEnter(Object);

UnsafeInstance.reflectGetUnsafe().monitorExit(Object);

在这里插入图片描述

在这里插入图片描述就是因为有元数据指针,可以知道对象的类

实例对象内存中存储在哪?

对象实例存在堆中,对象的引用存在线程的栈中,对象的元数据存在方法区或元空间

对象头

在这里插入图片描述

锁的升级优化过程(不可逆)

JVM内置锁,升级膨胀过程:1.6以后

无锁升级为偏向锁

如果线程竞争不激烈,从无锁升级为偏向锁,进行CAS操作,将对象头前23位改成线程id。

如果CAS操作成功,对象头和线程id一致,则认为当前线程已经获取了锁,虚拟机就可以不再进行任何同步操作。偏向锁可以提高带有同步但无竞争的程序性能。

在这里插入图片描述

在这里插入图片描述

进入到monitorenter

到达安全点

从无锁状态变为轻量级锁状态

在这里插入图片描述

在这里插入图片描述

首先把对象改为无锁状态

线程栈空间开辟锁记录lockRecord空间,把对象头MarkWord 复制到这里,

  • 修改Object mark word轻量级锁指针作用:告诉其他线程,该object monitor已被占用
  • owner指向object mark word作用:在下面的运行过程中,识别哪个对象被锁住了。

虚拟机将使用CAS操作尝试将对象的Mark Word更新为指向Lock Record的指针。如果这个更新动作成功了,那么这个线程就拥有了该对象的锁,并且对象Mark Word的锁标志位(Mark Word的最后2bit)将转变为“00”,即表示此对象处于轻量级锁定状态,

owner指针指向对象头,对象头中也有指针指向lockRecord

在这里插入图片描述

从轻量级锁升级到重量级锁

锁标志的状态值变为”10”,Mark Word中存储的就是指向重量级(互斥量)的指针。

在这里插入图片描述

解锁

与加锁一样通过CAS操作进行的,如果对象的Mark Word仍然指向着线程的锁记录,那就用CAS操作把对象当前的Mark Word和线程中复制的Displaced Mark Word替换回来(这也是为什么之前要复制的原因)

如果替换成功,整个同步过程就完成了。如果替换失败,说明有其他线程尝试过获取该锁,那就要在释放锁的同时,唤醒被挂起的线程。

轻量级锁优缺点

轻量级锁能提高程序同步性能的依据是“对于绝大部分的锁,在整个同步周期内都是不存在竞争的”,这是一个经验数据。

  • 如果没有竞争,轻量级锁使用CAS操作避免了使用互斥量的开销

  • 但如果存在锁竞争,除了互斥量的开销外,还额外发生了CAS操作,因此在有竞争的情况下,轻量级锁会比传统的重量级锁更慢。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值