Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何理解“;isOnSyncQueue”;AQS的功能_Java_Multithreading_Concurrency - Fatal编程技术网

Java 如何理解“;isOnSyncQueue”;AQS的功能

Java 如何理解“;isOnSyncQueue”;AQS的功能,java,multithreading,concurrency,Java,Multithreading,Concurrency,当我阅读Java关于AQS(AbstractQueuedSynchronizer)的源代码时,我有一个疑问 final boolean isOnSyncQueue(Node node) { if (node.waitStatus == Node.CONDITION || node.prev == null) return false; if (node.next != null) // If has successor, it must be on queue

当我阅读Java关于AQS(AbstractQueuedSynchronizer)的源代码时,我有一个疑问

final boolean isOnSyncQueue(Node node) {
    if (node.waitStatus == Node.CONDITION || node.prev == null)
        return false;
    if (node.next != null) // If has successor, it must be on queue
        return true;
    /*
     * node.prev can be non-null, but not yet on queue because
     * the CAS to place it on queue can fail. So we have to
     * traverse from tail to make sure it actually made it.  It
     * will always be near the tail in calls to this method, and
     * unless the CAS failed (which is unlikely), it will be
     * there, so we hardly ever traverse much.
     */
    return findNodeFromTail(node);
}
最主要的疑问是最后一条注释。当一个等待条件的线程被另一个调用
signal()
方法的线程通知时,它的节点已经进入同步队列

final boolean transferForSignal(Node node) {
    /*
     * If cannot change waitStatus, the node has been cancelled.
     */
    if (!node.compareAndSetWaitStatus(Node.CONDITION, 0))
        return false;

    /*
     * Splice onto queue and try to set waitStatus of predecessor to
     * indicate that thread is (probably) waiting. If cancelled or
     * attempt to set waitStatus fails, wake up to resync (in which
     * case the waitStatus can be transiently and harmlessly wrong).
     */
    Node p = enq(node);
    int ws = p.waitStatus;
    if (ws > 0 || !p.compareAndSetWaitStatus(ws, Node.SIGNAL))
        LockSupport.unpark(node.thread);
    return true;
}
如果另一个线程没有完全执行
enq(Node)
方法,则此节点将一致地尝试
compareAndSetTail(oldTail,Node)
,直到成功。执行完成后,可能会通知此线程

我可以想象这样一种情况,当
enq
方法调用时,这个线程是“意外唤醒”,并执行
isOnSyncQueue
方法。此时它的waitStatus not条件和prev设置为'enq',因此它可以满足注释所述。但是,由于节点CAS失败,调用
findNodeFromTail
方法时,它不在同步队列中。
findNodeFromTail
没有意义

enq
invoke成功,并且prev节点被取消时,它将取消该线程的连接,但是该线程被意外唤醒,
isOnSyncQueue
方法返回false,该线程再次被阻塞。在这个时候,它将不再是信号

if (ws > 0 || !p.compareAndSetWaitStatus(ws, Node.SIGNAL))
    LockSupport.unpark(node.thread);
下面是我说的(我不允许浏览图片):

那么,我说的对吗?或者你可以告诉我为什么?谢谢你的回答

thread1: transferForSignal()  enq()
thread2: surprise wake up. execute isOnSyncQueue() and return fasle
thread1: enq() execute finish and prev is cancelled or CAS fail, 
         LockSupport.unpark(node.thread), this is make no sense.
thread2: LockSupport.park(this) and won't be signalled because 
         LockSupport.unpark(node.thread) has been invoked.