从字节码上来看,看不出线程进入 wait 状态后,释放锁。
你在这段代码里当然看不出来了,invokevirtual #2这句已经在栈中压入了wait方法,释放锁的代码肯定要去wait方法里看。那虚拟机是怎么实现的呢?
你这个问题其实很复杂,可以从几个层面解答。
抽象层:
相信这个图很多人都看过,这是在抽象层面上,synchronized的工作原理,当然图中并没有涉及到锁的膨胀这一概念。调用wait()方法时,线程会被挂起,放入WaitSet中等待被notify/notifyAll唤醒,锁的释放就是在这个过程中实现的。
字节码层:
一般来说,我们都直接看JVM源码或JDK源码,看字节码的情况比较少。但既然这个问题中你提到了字节码,那么我们就从字节码说起。aload_0,invokevirtual #2,这两句相当于调用了this.wait(),也就是Object.wait()方法,字节码如下:
可以看到这个方法也没有包含释放锁的逻辑,而是调用了Object.wait(long)这个重载方法,aload_0,lconst_0,invokevirtual #15,这三句合起来的意思就是this.wait(0L)。Object.wait(long)方法的字节码如下:
想必你也看出来了,这里直接调用了本地C++方法,所以在字节码中是找不到你要的答案的。
这也是一些初学者的认识误区,以为JVM的逻辑都在字节码中执行。其