首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

java并发编程-AbstractQueuedSynchronizer公道锁和非公平锁分析(三)

2012-08-30 
java并发编程--AbstractQueuedSynchronizer公平锁和非公平锁分析(三)juc包中,aqs实现的公平锁和非公平锁的

java并发编程--AbstractQueuedSynchronizer公平锁和非公平锁分析(三)

juc包中,aqs实现的公平锁和非公平锁的最主要的区别是:非公平锁中,那些尝试获取锁且尚未进入等待队列的线程会和等待队列head结点的线程发生竞争。公平锁中,在获取锁时,增加了isFirst(current)判断,当且仅当,等待队列为空或当前线程是等待队列的头结点时,才可尝试获取锁。

?

?

1.1 NonfairSync.lock()?

final void lock() {if (compareAndSetState(0, 1))//没有进入等待队列,也可以获取锁setExclusiveOwnerThread(Thread.currentThread());elseacquire(1);}

?

2.1 FairSync.lock()

final void lock() {        acquire(1);}

?

2.2 FairSync.tryAcquire()

/**         * Fair version of tryAcquire.  Don't grant access unless         * recursive call or no waiters or is first.         */        protected final boolean tryAcquire(int acquires) {            final Thread current = Thread.currentThread();            int c = getState();            if (c == 0) {                if (isFirst(current) &&//只有等待队列为空或当前线程是队列头结点才可以获取锁                    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;        }

关于当前线程是否是队列头结点的判断,详见下面两个函数:?

?

2.3 AbstractQueuedSynchronizer.isFirst()

/**     * Return {@code true} if the queue is empty or if the given thread     * is at the head of the queue. This is reliable only if     * <tt>current</tt> is actually Thread.currentThread() of caller.     */    final boolean isFirst(Thread current) {        Node h, s;        return ((h = head) == null ||                ((s = h.next) != null && s.thread == current) ||                fullIsFirst(current));    }

?

2.4 AbstractQueuedSynchronizer.fullIsFirst()

final boolean fullIsFirst(Thread current) {        // same idea as fullGetFirstQueuedThread        Node h, s;        Thread firstThread = null;        if (((h = head) != null && (s = h.next) != null &&             s.prev == head && (firstThread = s.thread) != null))            return firstThread == current;        Node t = tail;        while (t != null && t != head) {            Thread tt = t.thread;            if (tt != null)                firstThread = tt;            t = t.prev;        }        return firstThread == current || firstThread == null;    }
?

总结:

线程为首结点成立的情况:

1.等待队列为空。

2.等待队列head的next结点的thread为当前线程(head.next.thread = currentThread),即线程为等待队列除哑结点外的第一个结点。

3.等待队列head结点到某个结点(暂命名为结点s),之间的所有结点的thread变量为null,且结点s的thread为当前线程。

?

热点排行