可重入锁ReentrantLock源码分析
2020-08-18 10:47:29 0 举报
可重入锁解析
作者其他创作
大纲/内容
不是当前获取锁线程
返回原尾结点
头结点状态为默认状态
修改成功
是否为0状态if (c == 0)
判定当前线程状态是否为0if (c == 0)
否
返回中断结果
非公平锁(new NonfairSync())Lock lock = new ReentrantLock();
尾结点为空
获取当前锁的状态int c = getState();
不是头结点
将当前节点的前指向尾结点node.prev = t;
返回true
返回无需进行中断
是
获取当前节点的上一个节点final Node p = node.predecessor();
设置锁状态setState(c);
返回进行中断
插入节点enq(node);
进行自我中断selfInterrupt();
设置当前线程为持有锁线程setExclusiveOwnerThread(current);
尝试获得锁tryAcquire(arg)
是头结点
尾节点是否为空if (pred != null)
对当前线程进行打断selfInterrupt();
判断状态是否大于0if (ws > 0) (状态是否为已取消)
当前线程是否为持有锁线程else if (current == getExclusiveOwnerThread())
循环像前面的节点寻找第一个状态不为取消的节点do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0);
状态是否为SIGNAL(等待唤醒)if (ws == Node.SIGNAL)
进行中断parkAndCheckInterrupt()
添加成功
尝试释放锁tryRelease(arg)
自旋for (;;)
头结点状态是否为默认状态h.waitStatus != 0
将当前节点设置为头结点setHead(node);
修改失败
判断尾结点是否为空if (t == null)
返回当前节点return node;
中断
将寻找到第一个非取消的节点的下一个节点设置为当前节点pred.next = node;
给程序加锁lock.lock();
非公平锁NonfairSync加锁过程
获取锁成功
获得锁失败
判断当前节点的上一个节点是否为头节点p == head
尝试释放锁tryRelease(int arg)
表示当前节线程为第一个插入到等待队列中线程
持有锁失败
头结点为空
返回获取锁成功/失败
尝试获得锁tryAcquire(arg)nonfairTryAcquire(acquires)
获取锁失败
不中断
获取当前等待队列的尾节点Node pred = tail;
判断当前线程是否为已经获取到排他锁的线程current == getExclusiveOwnerThread()
唤醒头结点unparkSuccessor(h);
非公平获取锁nonfairTryAcquire(acquires)
尾结点不为空
线程进行获得锁操作 acquire(1);
设置失败
获取当前节点的前一个节点的等待状态int ws = pred.waitStatus;
清空当前持有锁线程setExclusiveOwnerThread(null);
原尾结点的后节点指向当前节点t.next = node;
公平锁 FairSync加锁过程
返回是否释放锁
获得锁成功
判定当前线程是否为持有锁线程if (Thread.currentThread() != getExclusiveOwnerThread())
插入当前节点到等待队列中enq(node);
尝试获得的过程tryAcquire(arg)
取得当前线程final Thread current = Thread.currentThread();
将当前线程设置为获得锁线程setExclusiveOwnerThread(Thread.currentThread());
设置成功
将当前线程放入到等待队列状态设置为独占锁addWaiter(Node.EXCLUSIVE)
自旋for (;;)
是当前获取锁线程
抛出异常throw new IllegalMonitorStateException();
获取当前的等待队列的头结点Node h = head;
释放锁状态sync.release(1);
修改锁状态(重入锁过程)int nextc = c + acquires;setState(nextc);
解锁过程lock.unlock()
设置头结点=尾结点tail = head;
当前线程开始持有锁
创建ReentrantLock锁
头结点不为空
公平锁(new FairSync())Lock lock = new ReentrantLock(true);
返回尝试获取锁失败或成功
返回是否要进行中断
获取当前锁状态并减去传入参数int c = getState() - releases;
线程进行获得锁操作 acquire(1);
头结点是否为空h != null
添加到等待队列中addWaiter(Node.EXCLUSIVE)
返回false
将当前节点设置为头结点compareAndSetHead(new Node())
尝试失败
释放锁成功
持有锁成功
锁状态是否为0默认状态无线程持有当前锁
获取当前尾结点Node t = tail;
0 条评论
下一页