JUC篇-ReentrantLock(二)之公平同步队列

前言

在《JUC篇-ReentrantLock(一)》中提到了ReentrantLock一些基础使用和源码。从《JUC篇-ReentrantLock(一)》源码中也可以知道new ReentrantLock()获取的是一个非公平同步队列;而本篇主要讲述ReentrantLock的公平同步队列。

JUC篇-ReentrantLock(二)之公平同步队列

new ReentrantLock(#是否公平的参数)

源码分析

new ReentrantLock(true)

    public ReentrantLock(boolean fair) {
      //FairSync公平同步
      //NonfairSync非公平同步
        sync = fair ? new FairSync() : new NonfairSync();
    }

和非公平同步的区别是在于tryAcquire()方法;

@ReservedStackAccess
protected final boolean tryAcquire(int acquires) {
    final Thread current = Thread.currentThread();
    int c = getState();
    if (c == 0) {
      	//和非公平同步的区分在于多加了hasQueuedPredecessors方法判断
      	//判断队列中的最前面的节点是否==当前线程,如果是的话,就加锁
        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;
}
public final boolean hasQueuedPredecessors() {
    Node h, s;
    if ((h = head) != null) {
        if ((s = h.next) == null || s.waitStatus > 0) {
            s = null; // traverse in case of concurrent cancellation
            for (Node p = tail; p != h && p != null; p = p.prev) {
                if (p.waitStatus <= 0)
                    s = p;
            }
        }
 				//如果队列中存在前节点,且前节点不等于当前线程,
      	//则需要等待,返回true
        if (s != null && s.thread != Thread.currentThread())
            return true;
    }
    return false;
}

hasQueuedPredecessors方法中有waitStatus状态,下面是官网对waitStatus解释

Status field, taking on only the values: SIGNAL: The successor of this node is (or will soon be) blocked (via park), so the current node must unpark its successor when it releases or cancels. To avoid races, acquire methods must first indicate they need a signal, then retry the atomic acquire, and then, on failure, block. CANCELLED: This node is cancelled due to timeout or interrupt. Nodes never leave this state. In particular, a thread with cancelled node never again blocks. CONDITION: This node is currently on a condition queue. It will not be used as a sync queue node until transferred, at which time the status will be set to 0. (Use of this value here has nothing to do with the other uses of the field, but simplifies mechanics.) PROPAGATE: A releaseShared should be propagated to other nodes. This is set (for head node only) in doReleaseShared to ensure propagation continues, even if other operations have since intervened. 0: None of the above The values are arranged numerically to simplify use. Non-negative values mean that a node doesn't need to signal. So, most code doesn't need to check for particular values, just for sign. The field is initialized to 0 for normal sync nodes, and CONDITION for condition nodes. It is modified using CAS (or when possible, unconditional volatile writes).

总结

公平同步队列是需按照队列中的前后顺序去获取所执行程序。而非公平同步队列则是队列中哪个线程节点获取锁,哪个先执行。

一天一个java相关小知识。喜欢的同学,可以点赞、关注+收藏,后期还会推出其他框架源码分析。

如果有需要补充的地方,留言区见。

展开阅读全文

页面更新:2024-04-25

标签:队列   公平   节点   线程   前言   后期   加锁   源码   顺序   方法

1 2 3 4 5

上滑加载更多 ↓
推荐阅读:
友情链接:
更多:

本站资料均由网友自行发布提供,仅用于学习交流。如有版权问题,请与我联系,QQ:4156828  

© CopyRight 2008-2024 All Rights Reserved. Powered By bs178.com 闽ICP备11008920号-3
闽公网安备35020302034844号

Top