Java-Lock独占锁与共享锁原理

个人理解记录

ReentrantLock基于aqs实现,他的基本原理是aqs的status为0时表示锁被占用,为1时表示锁被释放。ReentrantLock在使用时需要显式的获取和释放锁,一般用try finally来实现,相对于synchronized,reentrantlock提供了功能更强大的api,例如超时锁、可中断锁、公平锁、非公平锁、非阻塞锁获取等等,ReentrantLock是独占锁,它分为公平锁和非公平锁两种模式,公平锁保证按照获取锁的顺序来得到锁,非公平锁则则可以进行抢占,而像countdownlatch、semaphore等组件是基于共享锁实现的,也就是同一时刻可以有多个线程获取锁,锁的数量由用户指定。

独占公平锁原理:
调用aqs的lock方法尝试获取锁
调用上层组件reentrantlock的trylock方法尝试获取同步状态
如果获取成功,则成功获取锁,如果获取失败,则被构造成node节点后,利用cas线程安全的加到同步对列的末尾
然后该线程进入自旋状态
自旋时首先判断前驱节点是否为头节点并且能否成功获取到同步状态,如果都成立,则成功获取锁,如果不成立,则先讲将其前驱节点等待状态设置为signal,然后利用Locksupport挂起,等待前驱线程唤醒当被前驱节点唤醒,且成功回去同步状态后,才成功获取到了锁。

对于释放锁,就是通过aqs设置同步状态为1的过程,同时唤醒后继节点

独占非公平锁:
独占非公平锁与公平锁的唯一区别是,在获取锁时,不管是否有线程在等待锁,直接通过aqs修改同步状态,进行锁抢占,如果抢占失败,那后面的流程就与公平锁一致了。

共享锁原理:
共享锁的基本流程与独占锁相同,主要区别在于判断锁获取的条件上,由于是共享锁,也就允许多个线程同时获取,所以同步状态的数量同时的大于1的,如果同步状态为非0,则线程就可以获取锁,只有当同步状态为0时,才说明共享数量的锁已经被全部获取,其余线程只能等待。
共享锁的释放过程正好与之相反,释放锁对应的AQS操作时增加同步状态的值。

你可能感兴趣的:(Code-Java)