JAVA锁机制V2(入门-精通)
2024-12-17 20:33:28 0 举报
锁Lock_JAVA_流程图_架构图_系统图_数据库
作者其他创作
大纲/内容
prev
1、Thread3线程会删除Condition 队列上的第一个节点(拿到第一个节点并将nextWaiter设置成null),这里的第一个节点里面封装的是Thread12、将上面节点添加到AQS队列中,并唤醒它
Thread2获取锁失败,会添加到AQS同步队列中。首先是初始化一个Node,它既是head,也是tail,也是t
next
线程获取锁成功
private volatile int state; // state=0表示无锁状态,>0表示重入次数private transient volatile Node head; // 双向链表头节点private transient volatile Node tail; // 双向链表尾节点span style=\
tryAcquire()
acquire()
AQS
AQS队列Node双向链表
state=1exclusiveOwnerThread=Thread1
thread=Thread2waitStatus=-1
lock()
线程获取锁失败
新tail
1、添加Thread1到Condition队列(由Node节点组成的单向链表)2、Thread1释放锁,并且触发AQS队列中的线程争抢锁3、挂起Thread1,等待其它线程来唤醒它
signalThread
Thread1释放锁
将Thread3封装成一个Node,添加到双向链表中结尾,并将其设置成tail节点。span style=\
AbstractQueuedSynchronizer
lock.lock()
thread=nullwaitStatus=0
Thread2
Thread1
awaitThread
thread=Thread1waitStatus=0
thread=Thread2waitStatus=0
head/t
thread=nullwaitStatus=-1
await过程
Condition队列Node单向链表
Condition等待队列
修改节点状态,并将Thread2和Thread3线程挂起来
tail
ReentrantLock
firstWaiter/lastWaiter
thread=Thread3waitStatus=0
Thread1释放锁,更新state和exclusiveOwnerThread
head
将Thread2封装成一个Node,添加到双向链表中结尾,并将其设置成tail节点。span style=\
释放锁过程
原head
head/tail/t
state=1exclusiveOwnerThread=Thread3
Sync
结束退出
state=1exclusiveOwnerThread=Thread2
从入门到精通
addWaiter()
AQS有三个关键变量state(加锁状态)exclusiveOwnerThread(加锁成功线程)Node(AQS加锁失败同步队列)
NonfairSync
AbstractOwnableSynchronizer
true/false
font color=\"#323232\
condition.await()
condition.signal()
AQS同步队列
获取lock成功
state=0exclusiveOwnerThread=null
原tail
private transient Thread exclusiveOwnerThread; // 用来存储获取锁的线程
await
Thread1获取锁,更新state和exclusiveOwnerThread此时head和tail都是null
1、看原head节点的下一个节点是否为null,不为null,则取消挂起状态,并开始争抢锁2、如果原head下一个节点为null,则从tail节点往前找,找到最靠近原head节点的Node,取span style=\
加锁过程
Thread3
Thread1获取锁成功,更新state和exclusiveOwnerThreadThread2获取锁失败,加入了AQS队列
其它线程释放锁后该线程重新加入锁竞争
nofireTryAcquire()
signal
Lock对象
获取lock失败
FairSync
acquireQueued()
Condition对象
signal过程
新head/t
0 条评论
下一页