基础篇

使用了synchronized关键字后,java底层编译后的指令中会有monitorenter(模拟特)和monitorexit(模拟蜕)两个指令。monitor的锁是支持重入加锁的
// 线程A
synchronized(myObject) { -> 类的class对象来走的
// 一大堆的代码
synchronized(myObject) {
// 一大堆的代码
}
}
image.png
(1) 如果一个线程第一次synchronized那里,获取到了myObject对象的monitor的锁,计数器加1,然后第二次synchronized那里,会再次获取myObject对象的monitor的锁,这个就是重入加锁了,然后计数器会再次加1,变成2
(2) 这个时候,其他的线程在第一次synchronized那里,会发现说myObject对象的monitor锁的计数器是大于0的,意味着被别人加锁了,然后此时线程就会进入block阻塞状态,什么都干不了,就是等着获取锁
(3)接着如果出了synchronized修饰的代码片段的范围,就会有一个monitorexit的指令,在底层。此时获取锁的线程就会对那个对象的monitor的计数器减1,如果有多次重入加锁就会对应多次减1,直到最后,计数器是0
(4)然后后面block住阻塞的线程,会再次尝试获取锁,但是只有一个线程可以获取到锁