流程图如下:
步骤1是线程在进入Contention List时阻塞等待之前,程会先尝试自旋使用CAS操作获取锁,如果获取不到就进入Contention List队列的尾部(所以不是公平锁)。
步骤2是Owner线程在解锁时,如果Entry List为空,那么会先将Contention List中队列尾部的部分线程移动到Entry List。(所以Contention List相当于是后进先出,所以也是不公平的)
步骤3是Owner线程在解锁时,如果Entry List不为空,从Entry List中取一个线程,让它成为OnDeck线程,Owner线程并不直接把锁传递给OnDeck线程,而是把锁竞争的权利交给OnDeck,OnDeck需要重新竞争锁,JVM中这种选择行为称为 “竞争切换”。(主要是与还没有进入到Contention List,还在自旋获取重量级锁的线程竞争)
步骤4就是OnDeck线程获取到锁,成为Owner线程进行执行。
等待和通知步骤(这是调用了wait()和notify()方法才有的步骤):
在同步块中,获得了锁的线程调用锁对象的Object.wait()方法,就是Owner线程调用锁对象的wait()方法进行等待,会移动到Wait Set中,并且会释放CPU资源,也同时释放锁,
就是当其他线程调用锁对象的Object.notify()方法,之前调用wait方法等待的这个线程才会从Wait Set移动到Entry List,等待获取锁。