synchronized的实现原理和锁升级 面试重点
1.synchronized的实现原理
synchronized是Java 中的一个很重要的关键字,主要用来加锁,synchronized所添加的锁有以下几个特点。synchronized的使用方法比较简单,主要可以用来修饰方法和代码块。根据其锁定的对象不同,可以用来定义同步方法和同步代码块。
方法级的同步是隐式的(同步方法)。同步方法的常量池中会有一个ACC_SYNCHRONIZED标志。当某个线程要访问某个方法的时候,会检查是否有ACC_SYNCHRONIZED,如果有设置,则需要先获得监视器锁,然后开始执行方法,方法执行之后再释放监视器锁。这时如果其他线程来请求执行方法,会因为无法获得监视器锁而被阻断住。值得注意的是,如果在方法执行过程中,发生了异常,并且方法内部并没有处理该异常,那么在异常被抛到方法外面之前监视器锁会被自动释放。
同步代码块使用monitorenter和monitorexit两个指令实现。 可以把执行monitorenter指令理解为加锁,执行monitorexit理解为释放锁。 每个对象维护着一个记录着被锁次数的计数器。未被锁定的对象的该计数器为0,当一个线程获得锁(执行 monitorenter)后,该计数器自增变为 1,当同一个线程再次获得该对象的锁的时候,计数器再次自增。当同一个线程释放锁(执行monitorexit指令)的时候,计数器再自减。当计数器为0的时候。锁将被释放,其他线程便可以获得锁。
2.synchronized特性
synchronized是Java中的一个很重要的关键字,主要用来加锁,synchronized具有以下特性:
互斥性
同一时间点,只有一个线程可以获得锁,获得锁的线程才可以处理被 synchronized 修饰的代码片段。
阻塞性
只有获得锁的线程才可以执行被synchronized 修饰的代码片段,未获得锁的线程只能阻塞,等待锁释放。
可重入性
如果一个线程已经获得锁,在锁未释放之前,再次请求锁的时候,是必然可以获得锁的
3.锁的具体表现:
4.monitor(监视锁)
这个机制的保障来源于监视锁Monitor,每个对象都拥有自己的监视锁Monitor。当我们尝试获得对象的锁的时候,其实是对该对象拥有的Monitor 进行操作。
5.synchronized锁的是什么?
6.synchronized的锁升级过程是怎样的?
6.1为什么要锁升级?
在JDK 1.6之后,synchronized锁的实现发生了一些变化,引入了“偏向锁”、“轻量级锁”和“重量级锁”三种不同的状态,用来适应不同场景下的锁竞争情况。
6.2 不同锁状态下的对象头中 mark word结构
在Java中,mark word的低两位用于表示锁的状态,分别为“01”(无锁状态)、“01”(偏向锁状态)、“00”(轻量级锁状态)和“10"(重量级锁状态)。但是由于无锁状态和偏向锁都是“01”,
所以在低三位引入偏向锁标记位,用“0“表示无锁,“1“表示偏向。
6.3 偏向锁
6.3.1偏向锁的撤销
6.4 轻量级锁
(1)轻量级加锁
(2)轻量级锁解锁
6.5 重量级锁
此时,如果一个线程想要获取该对象的锁,则需要先进入等待队列,等待该锁被释放。当锁被释放时,JVM 会从等待队列中选择一个线程唤醒,并将该线程的状态设置为“就绪”状态,然后等待该线程重新获取该对象的锁。
触发条件:当轻量级锁的CAS操作失败,轻量级锁升级为重量级锁。
6.6 锁的优缺点对比
原文地址:https://blog.csdn.net/weixin_69039908/article/details/140484596
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!