Synchronized原理和性质

上篇文章:Synchronized入门
一、性质
二、原理
三、缺陷
四、常见面试题

一、性质
1、可重入:指的是同一线程的外层函数获得锁之后,内层函数可以直接再次获取该锁。获得锁之后不需要重新获取,可直接获取,直到自己释放。
好处:避免死锁,提升封装性
粒度:线程而非调用
(1)同一个方法是可重入的
(2)不要求同一个方法
(3)可重入不需要在同一个类中
2、不可中断:一旦这个锁已经被别人获得了,如果我们还想获得,只能选择等待或者阻塞,直到正在用的线程释放这个锁,如果别人永远不释放,则永远等待。相比之下,lock可以拥有中断能力,第一可以有权中断,第二可以退出

二、原理
(1)加解锁原理
获取和释放锁的时机:内置锁
Synchronized是使用monitor进行操作的,锁的信息放在对象的头部,重点是monitorenter和monitorexit
我们可以通过反编译Class文件查看,反编译的命令是

javap -verbose 类名.Class

我们写一个简单的代码并且进行反编译,其中代码和反编译结果如下:

public class MonditoreTest {
	Lock lock=new ReentrantLock();
	public void method(){
		synchronized (this) {
			System.out.println("啦啦");
		}
	}
}

结果:
在这里插入图片描述
我们可以看到monitorenter和monitorexit的信息,可以看到一次monitorenter但是多次monitorexit,不是一对一对应的,因为有可能异常退出,有可能正常退出。

monitor其实是有一个锁的计数器的,monitorenter和monitorexit执行的时候也就是进行将锁的计数器加一或者减一

monitorenter的三种情况:
1、如果计数器为0,则没有被获取则立即获得,则计数器加一,别的线程看到就知道别占用了
2、如果有一把锁,需要进行重入的情况,则计数器累加,加1
3、如果monitore被其他线程持有了,那我去获取的时候就会得到我无法获得,需要阻塞,直到别的线程释放了

monitoreenterexit:对已经拥有的锁的拥有权才需进行释放,就是将计数器减一,如果计数器为0了,则没有使用权了,如果不是0,则说明重入了,则需要进行执行

(2)可重入原理
加锁次数计数器
JVM负责跟踪对象被加锁的次数
线程第一次给对象加锁的时候,计数变成1.每当这个相同的线程在此对象上再次获得锁的时候,计数会递增
每当任务离开时,计数递减,当计数为0时,锁被完全释放
(3)可见性原理
在这里插入图片描述
A将修改过的内容放在主内存中,并且在由B去获取、JMM控制主内存和本地内存的交互,来保证可见性。
可见性实现:被锁住的对象在释放之前肯定将修改的线程内存写入主内存中,在获取的时候也是从主内存中获取出来的,就保证了可见性
三、缺陷
1、效率低
(1)锁的释放情况少,试图获得锁是不能设置超时,不能中断一个正在试图获得锁的线程。
(2)锁的释放情况少:当一个线程获得了锁之后,其他线程也想获得锁,则其他线程只能等待,只有两种情况释放锁,执行完代码,释放锁,异常的情况下,释放锁,如果需要等待Io,或者其他情况,则其他线程只能等待,非常影响效率
(3)不够灵活:加锁和释放锁的时机单一,每个锁仅有单一的条件(某个对象),可能是不够的

Lock是可以设置时间并且进行中断的

四、常见面试题
1、使用注意点:
(1)锁对象不能为空,作用域不宜过大,避免死锁
(2)锁对象不能为空:因为锁的信息是保存在对象头中的
(3)作用域不宜过大:Synchronized锁包裹的范围,不需要串行的情况下并行工作提高效率
2、避免死锁

3、如何选择Lock和Synchronized
(1)如果可以的话,使用各种类,java.util.concurrent atomic类deng 不需要自己做同步工作
(2)如果Synchronized适用就使用Synchronized,不需要太多代码
(3)灵活性或者其他原因无法完成,则使用LOCK
建议思路:不出错
4、Synchronized使得同时只有一个线程可以执行,性能较差,有什么提升性能?
范围不能太广,其他的锁的实现方法
5、多个线程等待同一个Synchronized锁的时候,JVM如何选择下一个获取锁的是哪个线程?
随机的

总结:
总结:JVM会自动通过monitor来加锁和解锁,保证了同时只有一个线程可以执行指定代码,从而保证了线程安全,同时具有可重入性和不可中断的性质

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值