synchronized同步代码块加锁
synchronized被反汇编后会生成字节码指令monitorenter和monitorexit

monitorenter
synchronized的锁对象会关联一个monitor,这个monitor不是我们主动创建的,是JVM的线程执行到同步代码块时,发现对象没有monitor就会创建monitor。
monitor内部有两个重要的成员变量owner(拥有这把锁的线程),recursions(记录线程拥有锁的次数),当一个线程拥有monitor后其他线程只能等待。
monitorexit
1.能执行monitorexit指令的线程一定拥有当前对象的monitor的所有权的线程
2.执行monitorexit时会将monitor的进入数减1。当monitor的进入数减为0时,当前线程退出monitor,不再拥有monitor的所有权,此时其他被这个monitor阻塞的线程可以尝试去获取这个monitor的所有权
synchronized出现异常会释放锁

synchronized同步方法加锁

小结
通过javap反汇编看到了synchronized变成了monitorenter和monitorexit两个指令,每个锁对象都会关联一个monitor(监视器,真正的锁对象),它有两个重要的成员变量owner会保存获得锁的线程,recursions会保存线程获得锁的次数,当执行到monitorexit时,recursions会减1,当计数器减到0时这个线程就会释放锁。