显示锁及其实现

显示锁于内置锁能提供共同的互斥性和可见性,但是显示锁在功能上更加丰富,对于死锁提供了解决方案,支持定时获取锁,可中断获取锁(当线程在获取锁上阻塞时,能对中断作出响应),公平锁,非公平锁(有优势,主要体现在一个线程获取锁时,发现该锁已经被获取了,则将挂起阻塞知道锁被释放,线程被唤醒,线程阻塞挂起与被唤醒花销很大,假设这时候刚好有个线程也来获取锁,为什么不直接给它呢,反正最后都能获取到锁),读写锁(readWriteLock)。

分布式锁:

ReentrantLock的底层实现:

在讲解ReentrantLock之前,先来讲解下AbstractQuenueSychronized。数据结构:状态量state,隐形的FIFO同步队列,节点Node,Node节点又包含prevNode,nextNode,thread,waitStatus,nextWatier,其中waitStatus用于标示节点的状态:cancel,signal(标示后续的节点处于阻塞状态,每次插入一个后续节点时都置前置节点状态为signal),condition,propagate。操作:acquire:首先判断钩子函数tryAcquire是否成功,即是否允许当前线程进行,若不允许的话,则新建一个Node节点,将该Node节点添加到FIFO队列的尾部(必须保证添加操作的线程安全,采用CAS操作),然后设置前置节点(跳过那些cancel状态的前置节点)的状态为signal(线程安全操作,CAS),并且用locksupport.park()阻塞线程,然后循环等待当前的前置节点是Head节点(当前节点是head节点意味着自己将被唤醒),当前置节点是头节点时将再次调用tryAcquire()去获取同步状态()。release:调用钩子函tryRelease,然后同步更新Head节点的状态为初始状态,并用Locksupport.unpark()唤醒下一个正常的Node(非正常指null,cancel状态的Node)。

ReentrantLock是怎么通过AQS来实现的呢

ReentrantLock支持公平锁和非公平锁。底层通过继承AQS来实现公平锁和非公平锁。操作:tryLock(),公平锁:AQS里面的state状态表示锁的重入次数,实现tryAcquire方法,首先获取状态值,若状态值为0表明当前线程可以获取该锁,同步更新state状态值得,并将currentThread置为锁的拥有者,若状态值不为0则观察当前线程是否时线程所有者,若是则state++,若不是则返回false。公平锁:实现方式类似。只是在获取锁时,先从同步队列中看下是否有更早开始等待的锁,若有则返回false。release():状态值改变,线程拥有者置null。

posted @ 2017-04-09 15:41  虔诚的旅行者  阅读(161)  评论(0编辑  收藏  举报