简述synchronized的实现原理

synchronized是Java中用于实现线程同步的关键字,其实现原理基于JVM的内部机制。当一个线程试图访问一个synchronized代码块时,它必须先获取一个锁。这个锁与对象关联,通常是通过对象的监视器(Monitor)来实现的。每个Java对象都有一个与之关联的Monitor,这个Monitor充当了一种互斥锁的角色。

当一个线程想要访问某个对象的synchronized代码块时,它首先需要获取该对象的Monitor。如果该Monitor已经被其他线程持有,则当前线程将会被阻塞,直至Monitor变为可用状态。当线程完成synchronized块的代码执行后,它会释放Monitor,并把Monitor返还给对象池,这样其他线程才能获取Monitor并进入synchronized代码块。

此外,Synchronized的实现也涉及到JVM的内存交互操作,包括lock(锁定)和unlock(解锁)指令。当一个线程试图获取某个对象的Monitor锁时,它会执行lock指令来尝试获取该锁。如果这个锁已经被其他线程占有,那么当前线程将会被阻塞,直至锁变得可用。当一个线程持有了Monitor锁并且已完成对临界区资源的操作后,它将会执行unlock指令来释放该锁,从而使得其他线程有机会获取该锁并执行相应的临界区代码。

总结来说,synchronized的实现原理主要依赖于JVM的内部机制,通过对象监视器(Monitor)和内存交互操作来实现线程之间的同步和互斥访问。收到新的锁请求时首先自旋,如果通过自旋也没有获取锁资源,被放入ContentionList(该做法对于已经进入队列的线程是不公平的,体现了synchronized的不公平性)。为了防止ContentionList尾部的元素被大量线程进行CAS访问影响性能,Owner线程会在是释放锁时将ContentionList的部分线程移动到EntryList并指定某个线程(一般是最先进入的)为OnDeck线程。Owner并没有将锁直接传递给OnDeck线程而是把锁竞争的权利交给他,该行为叫做竞争切换,牺牲了公平性但提高了性能。获取到锁的OnDeck线程会变为Owner线程,未获取到的仍停留在EntryList中。Owner线程在被wait阻塞后会进入WaitSet,直
到某个时刻被唤醒再次进入EntryList。ContentionList、EntryList、WaitSet中的线程均为阻塞状态。当Owner线程执行完毕后会释放锁资源并变为!Owner状态。
 

 

你可能感兴趣的:(java)