大家好,我是奇喵小屋,一个分享技术和生活的博主。以下是我的主页。每个主页都更新了高质量的博客。创建起来并不容易。请关注掘金主页。将来会发布更多的MySQL。Redis、并发、JVM、分布式等面试热点知识,以及Java学习路线、面试重点、职业规划、面经等相关博文转载请注明出处!本文将带大家通过ReentrantLock和Semaphore,向大家展示AQS的独占模式和共享模式是如何实现的。ReentrantLock实现了AQS的独占模式,Semaphore实现了AQS的共享模式。获取锁而不被锁阻塞。ReentrantLock实现了AQS的独占模式。是可重入锁,也分为公平锁和非公平锁。公平锁:首先请求锁的线程必须先非公平地获得锁非公平锁比公平锁更高效。不公平的锁可能会导致线程饥饿——某些线程长时间无法获取资源。ReentrantLock的大部分方法都是由Sync及其子类实现的。ReentrantLock只暴露接口2。ReentrantLock获取锁2.1非公平锁2.2公平锁2.3公平锁和非公平锁的区别FairSync和NonfairSync的lock()和tryAcquire()逻辑是不同的。非公平锁会在lock()方法开始时尝试通过CAS修改同步状态获取锁,公平锁不会自旋,非公平锁和公平锁会调用tryAcquire()尝试获取锁当前驱节点是同步队列的第一个节点时锁定。在tryAcquire()中,如果状态为0,那么非公平锁不会关心节点在同步队列中的位置,直接尝试CAS修改状态获取锁;但是非公平锁关心节点的位置,会检查是否有前驱节点。如果有,以上两点都会被丢弃保证公平锁一定是——先获取锁的线程一定先获取锁,非公平锁不一定3.ReentrantLock释放锁公平lockreleaselock和unfairlockreleaselock使用相同的逻辑4.信号量介绍Semaphore实现了AQS的共享模式信号量,用于控制同时访问特定资源的线程数Reduced,当信号量为0时,线程无法访问资源,只有WATING等待信号量>0,如果资源用完,释放后会补充信号量(前面ReentrantLock中state=0表示锁可用,state不为0表示锁可用不可用,这里Semaphore的状态不为0表示锁可用,state为0表示锁不可用)5.Semaphore方法介绍//尝试获取一个信号量,如果信号量不为0,则设置semaphore-1,return//如果信号量为0,WAITING直到信号量不为0//Interruptiblepublicvoidacquire()throwsInterruptedException//尝试获取多个信号量,如果信号量足够,则semaphore-permits,return//如果信号量不够,WAITING直到信号量不为0//可以中断publicvoidacquire(intpermits)throwsInterruptedException//同acquire(),但不可中断publicvoidacquireUninterruptibly()//同acquire(intpermits),但不可中断publicvoidacquireUninterruptibly(intpermits)//释放一个信号量publicvoidrelease()//释放一个信号量publicvoidrelease(intpermits)6.方法详解6.1底层ofvoidacquire(intpermits)仍然是AQS共享模式获取锁的公平模式——FariSync中的tryAcquireShared(intacquires).png)非公平模式——NonfairSync中的tryAcquireShared(intacquires)在Sync中调用nonfairTryAcquireShared(intacquires)即一组Sync实现tryReleaseShared(intreleases)
