美文网首页
ReentrantLock之公平锁FairSync()

ReentrantLock之公平锁FairSync()

作者: 火兰人一个 | 来源:发表于2017-08-28 22:23 被阅读0次

直接进入lock()方法的tryAcquire方法

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()) { //代表当前有线程持有独占状态,并且不是当前线程。所以当前线程不能持有独占,直接返回false

intnextc = c + acquires;

if(nextc <0)

throw newError("Maximum lock count exceeded");

setState(nextc);

return true;

}

return false;

}

-------------------------------------------------------

分析hasQueuedPredecessors方法,

public final boolean hasQueuedPredecessors() {

// The correctness of this depends on head being initialized

// before tail and on head.next being accurate if the current

// thread is first in queue.

Node t =tail;// Read fields in reverse initialization order

Node h =head;

Node s;

return

h != t && 

((s = h.next) ==null|| s.thread!= Thread.currentThread());

}

1、当头结点和尾节点不相等并且 如果head节点的next节点s不为空,并且s不是当前线程。代表头节点执行完后s节点有可能被执行。当前线程无法参与竞争,所以返回true。

2、当头结点和尾节点不相等并且 如果head节点的next节点s不为空,并且s是当前线程。代表头节点执行完后s节点(当前线程)有可能被执行所以返回fasle。(代表上一层可以去竞争独占状态)

3、当头结点和尾节点不相等并且 如果head节点的next节点s为空,那么直接返回true,代表头节点后面没有节点。即当前线程不是头节点的next节点。返回true。不直接参与竞争

4、当头结点和尾节点相等,返回false,代表这个节点执行完之后没有节点在同步队列,当前线程可以直接参与竞争

以上四点保证了如果有其他的线程在头节点的next上等待并且head节点的next节点不是当前节点时,那么这个线程不能直接参与竞争,只能通过后面的循环cas方法去获取独占状态。在非公平锁中,当当前线程去获取state是0时,当前线程可以直接通过cas方法去尝试获取状态,一旦成功,那么如果在头节点后面原本有符合条件的等待执行的线程A,就无法获取独占状态,因此,此时对于A就是不公平的。

其它的逻辑都和非公平锁一样。

相关文章

网友评论

      本文标题:ReentrantLock之公平锁FairSync()

      本文链接:https://www.haomeiwen.com/subject/fhbgdxtx.html