一:锁的原理结构
(1)锁对象内部维护了一个同步管理器的对象AbstractQueuedSynchronizer,AbstractOwnableSynchronizer
(2)该对象其实是一个抽象类,具体的锁的管理器继承该抽象类
(3)该抽象类的关键属性有:---->Thread exclusiveOwnerThread(获取锁的线程对象)
----> Node head(首节点,正在拥有当前锁的线程构造的Node对象)
---->Node tail(尾巴节点,等待获取锁的线程构造的双向链表结构的队列的最后一个节点)
---->int state(当前该锁被线程争抢的状态,如果state=0,表示无线程争抢该锁,如果state>0则表示已经有线程拥有该锁)
二:锁中的Node队列的结构
(1)所有的线程在执行到获取锁的代码的部分,都会调用同步管理器的lock()方法,如果有线程获取锁,则将该线程构造成node对象,添加到队列尾部,并调用系统命令阻塞当前线程。也就是代码执行到这,当前线程就不再执行。
(2)拥有锁的线程,在释放锁的时候,会唤醒自己的后继节点的线程,让其争抢锁。
(3)Node的内部结构属性
--->int waitStatus(当前node的线程在争抢锁过程的状态标识)
--->Node prev(当前node的上一个node的引用,前驱节点)
--->Node next(当前node的下一个INITALnode的引用,后继节点)
--->Thread thread(当前node所代表的线程的线程对象)
--->Node nextWaiter(下一个等待着的node)
(4)node等待状态的的含义
CANCELLED = 1:由于同步队列中等待线程等待超时或被中断,需要从同步队列中取消等待,节点进入该状态不会再变化
SIGNAL = -1:后继节点线程处于等待状态,而当前节点的线程如果释放了同步状态或者被取消,将会通知后继节点,使后继节点得以运行。
CONDITION = -2:在等待队列中,节点线程等待在Condition上,当其他线程对Condition调用了signal()方法后,该节点将会从等待队列中转移到同步队列中。加入到对同步状态的获取中。
PROPAGATE = -3:表示下一次共享式同步状态获取将会无条件被传播下去。
INITIAL=0:初始化状态
三:公平锁和非公平锁的区别
(1)公平锁的锁获取,严格按照等待顺序进行锁获取,在获取锁的时候有一个判断hasQueuedPredeccssors(),同步队列中是否有前驱节点在等待获取锁,如果有,则放弃获取锁,而是添加到队尾,排队获取锁
(2)非公平锁,是获取锁的顺序是随机的,甚至,有的线程可能会一直无法获取锁,出现线程饥饿情况。
(3)公平锁的性能往往没有非公平锁的性能高,因为它需要排队,则需要进行程序状态的切换,要比非公平锁的切换次数多。
四:锁的获取和释放的过程图