synchronized 关键字提供了一种互斥极致追击,也就是说在同一时刻,只能有一个线程访问同步资源,很多资料、书籍将synchronized(mutex)称为锁,其实这种说法是不严谨的,准确的讲应该是某线程获取了与mutex关联的monitor锁(当然写程序的时候知道它想要表达的意思即可)
注意:javap反编译观察指令可以发现monitorenter和monitorexit是成对出现的(有些时候会出现一个monitorenter多个monitorexit,但是每一个monitorexit之前必有对应的monitorenter,这是肯定的)
1、MonitorEnter
每个对象都与monitor相关联,一个monitor的lock的锁只能被一个线程在同一时间获得,在一个线程尝试获得与对象关联monitor的所有权时会发生如下的几件事情。
(1)如果monitor的计数器为0,则意味着该monitor的lock还没有被获得,某个线程获得之后将立即对该计数器加一,从此该线程就是这个monitor的所有者了
(2)如果一个已经拥有该monitor的所有权的线程重入,则会导致monitor计数器再次累加1
(3)如果monitor已经被其他线程所拥有,则其他线程尝试获取该monitor的所有权时,会被陷入阻塞状态直到monitor计数器变为0,才能再次尝试获取对monitor的所有权
2、MonitorExit
释放对monitor的所有权,想要释放对某个对象关联的monitor的所有权的前提是,你曾经获得了所有权。释放monitor所有权的过程比较简单,就是将monitor的计数器减一,如果计数器的结果为0,那就意味着该线程不再拥有对该monitor的所有权,通俗的讲就是解锁。与此同时被该monitor block的线程将再次尝试获得对该monitor的所有权。