Synchronized 的原理

Synchronized代码块是由一对monitorenter(持有monitor对象)/monitorexit(释放monitor对象)指令实现的,monitor对象是同步的基本实现。而synchronized方法JVM使用ACC_SYNCHRONIZED访问标志来判断是否是一个同步方法,从而执行相应的同步调用。

Java6之前,monitor的实现是通过操作系统的互斥锁,因为需要进行用户态到内核态的切换,所以同步操作是一个没有差别的重量级操作。

现代的(Oracle)JDK中,JVM对这种情况进行了大刀阔斧的改进,提供了三种Monitor的实现方式,也是三种不同的锁:

偏向锁、轻量级锁、重量级锁。大大改进了其性能。

为了优化synchronized运行机制,JVM会进行锁的升级和降级。JVM会检测不同的竞争情况,切换合适的锁去实现。

1.synchronized优化后,锁机制的简单介绍:

1.自旋锁:线程自旋就是让CPU做无用功,目的是霸着CPU不放,等待获取锁,时间过长,影响性能,时间太短,又达不到延迟阻塞的目的。

2.偏向锁:当线程第一次获得了监视对象,之后让监视对象“偏向“这个线程,之后的多次调用则避免了CAS操作,说白了就是设一个变量,当变量为true时,则无需再走各种加锁/解锁的流程了。

3.轻量级锁:轻量级锁是由偏向锁升级而来。偏向锁运行在一个线程进入同步块的情况下,当第二个线程加入锁的竞争的时候,偏向锁就会升级为轻量级锁。

4.重量级锁:指当锁为轻量级锁时,另一个线程通过自旋获取锁,当自旋到一定次数时,还是没有获取锁时,该线程就会进入阻塞,该锁就会膨胀为重量级锁。重量级锁会让它申请的线程进入阻塞,性能降低。

2.说一下你对synchronized关键字所涉及的类锁,方法锁,重入锁的理解

1.类锁:synchronized修饰静态方法获取的是类锁(类的字节码文件对象)。

2.对象锁:synchronized修饰普通方法或者代码块获取的是对象锁。这种机制确保了同一时刻对于每一个类的实例,其所有被synchronized修饰的成员变量,最多只能有一个在执行,从而有效避免了类成员变量之间的访问冲突。

他俩是不冲突的,就是说,获取到类锁的线程和获取到对象锁的线程是不冲突的。

3.可重入锁:又称递归锁,是指在同一个线程获取到一个外层方法的锁时,在进入内层方法时,可以自动获取锁,继续执行。

可重入锁的好处是:可以一定程度上避免死锁。

3.wait和sleep的区别;

1.最大的区别是:在等待期间,wait会释放锁,sleep不会释放锁。

2.wait通常用于线程间交互,sleep用于暂停执行。

3.wait是Object类定义的方法,sleep是Thread类定义的方法。

4.wait会改变锁的行为。

5.调用wait,失去CPU执行时间,需要另外一个线程调用notify/notifyAll,才能重新获取CPU执行时间。

4.notify的运行过程

线程A调用wait(),让出锁,自己进入等待状态,同时加入等待锁对象的队列。之后线程B获取到锁,调用notify()通知等待队列,之后线程A进入阻塞队列,等线程B释放锁。线程A通过竞争,得到锁,之后继续执行wait()方法后面的语句。

5.synchronized和Lock的区别

1.存在层次:synchronized是Java关键字,在JVM层面上。lock是一个类,底层由CAS + Volatile实现。

2.锁的释放:获得锁的线程执行完同步代码后释放锁,或者发生异常由JVM让线程释放锁。在finally里面必须释放锁,不然容易造成死锁。

3.锁的获取:线程A获得锁,那么线程B等待,线程A阻塞,线程B一直等待。分情况而定,lock有几种获取锁的方式,大致是可以尝试获取锁,线程不用一直等待。

4.锁的状态:不能判断,lock可以判断。

5.锁类型:可重入,不可中断,非公平。lock可重入,可判断,可公平。

6.性能:少量同步,lock适用于大量同步。

lock是乐观锁,synchronized是悲观锁,比较消耗性能。但是jdk1.6之后,经过大量优化,在并发量不大时,性能可能还优于lock。

 

 

参考文章:https://juejin.im/post/5e5c5c52f265da575f4e7558#heading-115

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值