自旋锁
jdk的底层锁的实现除了synchronized关键字外,都是基于AQS(AbstractQueuedSynchronizer)来实现的, 那么就着重理解一下AQS。 其实在上一讲可重入锁中,我就是将自定义锁继承了AbstractQueuedSynchronizer, 它其实主要维护的就是一个维护volatile int state(代表共享资源)和一个FIFO线程等待队列(多线程争用资源被阻塞时会进入此队列)。 队列中的每个节点是对线程的一个封装,它保存着线程的引用(thread)、状态(waitStatus)、前驱节点(prev)、后继节点(next)。
其实说到自旋锁又会提起公平锁和非公平锁的机制,在公平锁的场景下,当锁的同步状态被释放后,同步队列中的首节点就会被唤醒,获取到锁。 而非公平锁,当同步状态释放的时候有一个线程进入获取锁,就可能会优先于队列中的线程获取到锁。 因为非公平锁减少了线程挂起的几率,后来的线程有一定几率逃离被挂起的开销,所以ReentrantLock默认采用的是非公平锁。
再说会自旋锁,当线程进入到同步队列中后,就会做忙循环,直到获取到同步态位置。 这里还有很多细节需要说明,留个 //TODO