Board logo

标题: Java并发编程-再谈 AbstractQueuedSynchronizer 1 :独占模式(2) [打印本页]

作者: look_w    时间: 2019-1-17 19:37     标题: Java并发编程-再谈 AbstractQueuedSynchronizer 1 :独占模式(2)

acquireQueued队列构建好了,下一步就是在必要的时候从队列里面拿出一个Node了,这就是acquireQueued方法,顾名思义,从队列里面acquire。看下acquireQueued方法的实现:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
final boolean acquireQueued(final Node node, int arg) {
    boolean failed = true;
    try {
        boolean interrupted = false;
        for (;;) {
            final Node p = node.prevecessor();
            if (p == head && tryAcquire(arg)) {
                setHead(node);
                p.next = null; // help GC
                failed = false;
                return interrupted;
            }
            if (shouldParkAfterFailedAcquire(p, node) &&
                parkAndCheckInterrupt())
                interrupted = true;
        }
    } finally {
        if (failed)
            cancelAcquire(node);
    }
}



这段代码描述了几件事:
看一下第一步shouldParkAfterFailedAcquire代码做了什么:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
private static boolean shouldParkAfterFailedAcquire(Node prev, Node node) {
    int ws = prev.waitStatus;
    if (ws == Node.SIGNAL)
        /*
         * This node has already set status asking a release
         * to signal it, so it can safely park.
         */
        return true;
    if (ws > 0) {
        /*
         * prevecessor was cancelled. Skip over prevecessors and
         * indicate retry.
         */
        do {
            node.prev = prev = prev.prev;
        } while (prev.waitStatus > 0);
        prev.next = node;
    } else {
        /*
         * waitStatus must be 0 or PROPAGATE.  Indicate that we
         * need a signal, but don't park yet.  Caller will need to
         * retry to make sure it cannot acquire before parking.
         */
        compareAndSetWaitStatus(prev, ws, Node.SIGNAL);
    }
    return false;
}



这里每个节点判断它前驱节点的状态,如果:
如果判断判断应当park,那么parkAndCheckInterrupt方法:
1
2
3
4
private final boolean parkAndCheckInterrupt() {
      LockSupport.park(this);
      return Thread.interrupted();
}



利用LockSupport的park方法让当前线程阻塞。




欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) Powered by Discuz! 7.0.0