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

独自空忆成欢 提交于 2020-12-12 02:45:03

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)。

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!