基础面试题—— synchronized是怎么实现的?

synchronized 是 Java 中的关键字,用于实现线程间的同步。
它可以用于方法或代码块上,确保同一时刻只有一个线程可以执行被 synchronized 修饰的代码块或方法,从而避免多线程环境中的并发问题。

synchronized 是 JVM 提供的原生机制,能保证可见性、原子性和有序性

synchronized 的实现原理:

synchronized 的底层实现依赖于 JVM 中的 对象监视器(Monitor) 机制。
每个对象的对象头中包含的元数据,其中之一就是用来实现 synchronized 的锁标志位。

synchronized方法级的同步是隐式的,当某个线程要访问同步方法的时候,
会先检查是否有ACC_synchronized标志,如果有就需要先获得监视器锁,然后在执行方法,等到执行完后再释放监视器锁。
如果有其它线程在synchronized同步方法执行过程中,再次执行这个方法,会因为无法获得监视器锁而被阻断。

synchronized同步代码块使用monitor enter 和 monitor exit两个指令实现,
可以把monitor enter理解为加锁,monitor exit理解为释放锁
每个对象都维护着一个被锁次数的计数器,执行monitor enter计数器自增,
执行monitor exit计数器自减,当计数器为0时,锁将被释放,其它线程便可以获得锁

线程在退出 synchronized 方法或代码块 或因抛出异常而离开代码块时,会自动释放锁

synchronized 锁有几个特点:
互斥性:同一时间,只能有一个线程可以获得锁
阻塞性:只能获得锁的线程可以执行synchronized修饰的代码片段,未获取锁的会被阻塞,等待锁的释放
可重入性:如果一个线程已经获得锁,在锁未被释放之前,再次请求锁的时候,是必然可以获得锁的

——————————————————————————

synchronized 锁的实现机制中存在锁的升级过程,以提高性能和减少不必要的线程争用。锁的升级主要涉及三种锁的状态:偏向锁、轻量级锁、和重量级锁。
JVM对于同步锁的处理是从偏向锁开始的,随着竞争越来越激烈,处理方式从偏向锁升级到轻量级锁,最终升级到重量级锁。

synchronized 锁升级:

偏向锁: 只有一个线程争夺时,这个线程来了不加锁。

轻量级锁: 少量线程来了之后,先尝试自旋,不挂起线程。

注意:挂起线程和恢复线程的操作都需要转入内核态中完成这些操作,给系统的并发性带来很大的压力。

重量级锁: 排队挂起线程,升级到重量级锁后,所有等待的线程都会被阻塞在操作系统的调度队列中,等待唤醒

在低竞争的情况下,偏向锁和轻量级锁可以大幅减少锁的开销,而在高竞争的情况下,重量级锁则保证了线程的正确性。

锁的降级:
JVM 允许从重量级锁降级为轻量级锁,或者轻量级锁降级为偏向锁,但这种降级并不常见,且主要由 JVM 内部控制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值