码迷,mamicode.com
首页 > 编程语言 > 详细

Java锁之重入锁(Reentrantlock)原理,公平锁与非公平锁

时间:2018-02-11 14:41:59      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:ant   等待队列   双向   sync   设置   pos   get   异常   final   

1、特点:

已获取锁的线程再次请求锁,可以直接获取。

2、实现:

自定义内部类 Sync,继承 AbstarctQueuedSynchronizer :

2.1、获取锁:lock() 

a、公平锁:

acquire(1)

b、非公平锁:

if (compareAndSetState(0, 1))

        //CAS,当前 state 为0,当前线程占有锁:
  setExclusiveOwnerThread(Thread.currentThread());
else acquire(1);

b.1 AbstarctQueuedSynchronizer acquire(int acquires)

然后是 acquire(1) ——>调用父类 AbstarctQueuedSynchronizer acquire(int acquires)

public final void acquire(int arg) {
         if (!tryAcquire(arg) &&
             acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
         selfInterrupt();
}

即如果未获取锁,将请求锁线程加入等待双向队列尾部。然后给当前线程发出中断命令。

Node.EXCLUSIVE = null,

addWaiter(Node node) 将 null 加入等待队列尾部,双向队列。

acquireQueued() 时候再次tryAcquire(arg)

b.2 ReetrantLock tryAcquire(int acquires) 

ReetrantLock 继承 自AbstarctQueuedSynchronizer  的 tryAcquire(int acquires) 如下(使用的 <模板模式>):

根据当前 state 判断当前线程可否获取锁,tryAcquire(int acquires):

如果没有线程持有当前锁:if  0 == getState():

公平锁:CAS将 state 设置为当前占有次数,则将队列中第一个线程唤醒,使其占有锁。

非公平锁:CAS将 state 设置为当前占有次数,直接使当前线程占有锁。

 

如果当前线程持有锁:else if current == getExclusiveOwnerThread(),则将其持有状态值加上aquires。

2.2、释放锁:unlock() ——>AbstarctQueuedSynchronizer   release(1) ——> sync.tryRelease(1)

state = getState -1

若当前线程非持有锁线程,抛异常;

state == 0,当前持有锁线程置空;

否则,setState(state)。

 

Java锁之重入锁(Reentrantlock)原理,公平锁与非公平锁

标签:ant   等待队列   双向   sync   设置   pos   get   异常   final   

原文地址:https://www.cnblogs.com/codegod/p/8440848.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!