【第22期】观点:IT 行业加班,到底有没有价值?

Reentrantlock源码解析

原创 2016年05月31日 17:09:15

Reentrantlock及可重入锁,读源码首先要看下它的outline:
这里写图片描述
其核心就是公平锁fairSync和非公平送NonFairSync
我们可以看到这两个锁有共同的方法:lock();

  1. fairSync
 final void lock() {
            acquire(1);
        }
  1. NonfairSync
final void lock() {
            if (compareAndSetState(0, 1))
                setExclusiveOwnerThread(Thread.currentThread());
            else
                acquire(1);
        }

在资源没有被占用的情况下:

非公平锁是: 先state+1,然后直接得到锁,
而公平锁则是: 先尝试去获取锁,如果得到了锁则state+1.

如果是同一线程,再次申请锁

两种锁,表现基本一致,可以参考下面的代码块. (只是这段代码块在不同函数中)
fairSync:

protected final boolean tryAcquire(int acquires) {
            final Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedPredecessors() &&
                    compareAndSetState(0, acquires)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            }
            else if (current == getExclusiveOwnerThread()) {
                int nextc = c + acquires;
                if (nextc < 0)
                    throw new Error("Maximum lock count exceeded");
                setState(nextc);
                return true;
            }
            return false;
        }

NonfairSync

protected final boolean tryAcquire(int acquires) {
            return nonfairTryAcquire(acquires);
        }

如果是不同线程申请锁:

从业务逻辑来看,公平锁和非公平锁唯一的区别就是需要判断当前线程是不是链表头.但是一直有一点不明白的,在c==0的情况下, 不是就可以说明已经是表头了吗? 为什么还要检查 isFirst(current). compareAndSetState(0, acquires) 也可以保证在并发的情况下只有state=0才能获取锁.

总结

非公平锁,和公平锁只有在state=0的时候,业务逻辑不一样.
在stage=0的时候,非公平锁是直接获取锁,没有维护等待队列.
在stage=0的时候, 公平锁依然需要检查当前线程是否是等待队列的第一个.

版权声明:本文为博主原创文章,未经博主允许不得转载。 举报

相关文章推荐

ReentrantLock源码解析

Lock特性lock接口提供synchronized关键字不具备的主要特性 特性 描述 尝试非阻塞的获取锁 当前线程尝试获取锁,如果这一时刻锁没有被其他线程获取到,则成功获取并持有锁 ...
  • juded
  • juded
  • 2017-05-26 11:09
  • 48

Jdk1.6 JUC源码解析(7)-locks-ReentrantLock

Jdk1.6 JUC源码解析(7)-locks-ReentrantLock 作者:大飞

java.util.concurrent包图文源码解析(二)——ReentrantLock

看这一篇时候先看第一篇,把类的继承关系弄清楚。java.util.concurrent包图文源码解析(一) ReentrantLock,意思就是可重入的锁,在JAVA环境下 ReentrantLoc...

ReentrantLock源码之二unlock方法解析(锁的释放)

1.ReentrantLock.unlock()分析 (1)首先尝试释放锁,如果要求释放数等于锁状态数,那么将锁状态位清0,清除锁所有者,返回true;否则返回false;(2)如果(1)返回的是true,说明锁完全释放。接下来将检查等待队列,并选择一个waitStatus处于等待状态的节点下的线程unpark(恢复),选择的依据是从尾节点开始,选取最靠近头节点的等待节点,同时清理队列中线程被取消的节点;(3)如果(1)返回f

java并发编程——ReentrantLock源码

ReentrantLock实现了Lock接口,其中通过使用AbstractQueuedSynchronizer实现了公平锁与非公平锁。 先看ReentrantLock.Sync:public cla...
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)