16232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson/* 26232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Written by Doug Lea with assistance from members of JCP JSR-166 36232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Expert Group and released to the public domain, as explained at 4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/ 56232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 66232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 76232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonpackage java.util.concurrent.locks; 891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.concurrent.TimeUnit; 991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.ArrayList; 1091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.Collection; 1191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravleimport java.util.Date; 126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonimport sun.misc.Unsafe; 136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson/** 156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * A version of {@link AbstractQueuedSynchronizer} in 1691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * which synchronization state is maintained as a {@code long}. 176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * This class has exactly the same structure, properties, and methods 1891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * as {@code AbstractQueuedSynchronizer} with the exception 196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * that all state-related parameters and results are defined 2091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * as {@code long} rather than {@code int}. This class 216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * may be useful when creating synchronizers such as 226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * multilevel locks and barriers that require 236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 64 bits of state. 246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>See {@link AbstractQueuedSynchronizer} for usage 266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * notes and examples. 276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @since 1.6 296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @author Doug Lea 306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilsonpublic abstract class AbstractQueuedLongSynchronizer 326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson extends AbstractOwnableSynchronizer 336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson implements java.io.Serializable { 346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final long serialVersionUID = 7373984972572414692L; 366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson To keep sources in sync, the remainder of this source file is 396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson exactly cloned from AbstractQueuedSynchronizer, replacing class 406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson name and changing ints related with sync state to longs. Please 416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson keep it that way. 426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 4591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Creates a new {@code AbstractQueuedLongSynchronizer} instance 466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * with initial synchronization state of zero. 476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected AbstractQueuedLongSynchronizer() { } 496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Wait queue node class. 526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>The wait queue is a variant of a "CLH" (Craig, Landin, and 546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Hagersten) lock queue. CLH locks are normally used for 556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * spinlocks. We instead use them for blocking synchronizers, but 566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * use the same basic tactic of holding some of the control 576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * information about a thread in the predecessor of its node. A 586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * "status" field in each node keeps track of whether a thread 596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * should block. A node is signalled when its predecessor 606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * releases. Each node of the queue otherwise serves as a 616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * specific-notification-style monitor holding a single waiting 626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * thread. The status field does NOT control whether threads are 636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * granted locks etc though. A thread may try to acquire if it is 646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * first in the queue. But being first does not guarantee success; 656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * it only gives the right to contend. So the currently released 666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * contender thread may need to rewait. 676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>To enqueue into a CLH lock, you atomically splice it in as new 696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * tail. To dequeue, you just set the head field. 706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <pre> 716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * +------+ prev +-----+ +-----+ 726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * head | | <---- | | <---- | | tail 736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * +------+ +-----+ +-----+ 746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * </pre> 756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>Insertion into a CLH queue requires only a single atomic 776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * operation on "tail", so there is a simple atomic point of 7891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * demarcation from unqueued to queued. Similarly, dequeuing 796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * involves only updating the "head". However, it takes a bit 806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * more work for nodes to determine who their successors are, 816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * in part to deal with possible cancellation due to timeouts 826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and interrupts. 836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>The "prev" links (not used in original CLH locks), are mainly 856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * needed to handle cancellation. If a node is cancelled, its 866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * successor is (normally) relinked to a non-cancelled 876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * predecessor. For explanation of similar mechanics in the case 886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * of spin locks, see the papers by Scott and Scherer at 896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * http://www.cs.rochester.edu/u/scott/synchronization/ 906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>We also use "next" links to implement blocking mechanics. 926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The thread id for each node is kept in its own node, so a 936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * predecessor signals the next node to wake up by traversing 946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * next link to determine which thread it is. Determination of 956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * successor must avoid races with newly queued nodes to set 966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the "next" fields of their predecessors. This is solved 976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * when necessary by checking backwards from the atomically 986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * updated "tail" when a node's successor appears to be null. 996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * (Or, said differently, the next-links are an optimization 1006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * so that we don't usually need a backward scan.) 1016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>Cancellation introduces some conservatism to the basic 1036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * algorithms. Since we must poll for cancellation of other 1046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * nodes, we can miss noticing whether a cancelled node is 1056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * ahead or behind us. This is dealt with by always unparking 1066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * successors upon cancellation, allowing them to stabilize on 1076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * a new predecessor, unless we can identify an uncancelled 1086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * predecessor who will carry this responsibility. 1096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>CLH queues need a dummy header node to get started. But 1116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * we don't create them on construction, because it would be wasted 1126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * effort if there is never contention. Instead, the node 1136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is constructed and head and tail pointers are set upon first 1146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * contention. 1156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>Threads waiting on Conditions use the same nodes, but 1176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * use an additional link. Conditions only need to link nodes 1186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * in simple (non-concurrent) linked queues because they are 1196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * only accessed when exclusively held. Upon await, a node is 1206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * inserted into a condition queue. Upon signal, the node is 1216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * transferred to the main queue. A special value of status 1226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * field is used to mark which queue a node is on. 1236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>Thanks go to Dave Dice, Mark Moir, Victor Luchangco, Bill 1256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Scherer and Michael Scott, along with members of JSR-166 1266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * expert group, for helpful ideas, discussions, and critiques 1276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * on the design of this class. 1286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 1296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static final class Node { 1306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** Marker to indicate a node is waiting in shared mode */ 1316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static final Node SHARED = new Node(); 1326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** Marker to indicate a node is waiting in exclusive mode */ 1336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static final Node EXCLUSIVE = null; 1346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** waitStatus value to indicate thread has cancelled */ 1366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static final int CANCELLED = 1; 1376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** waitStatus value to indicate successor's thread needs unparking */ 1386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static final int SIGNAL = -1; 1396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** waitStatus value to indicate thread is waiting on condition */ 1406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static final int CONDITION = -2; 1416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 1426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * waitStatus value to indicate the next acquireShared should 1436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * unconditionally propagate 1446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 1456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static final int PROPAGATE = -3; 1466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 1486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Status field, taking on only the values: 1496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * SIGNAL: The successor of this node is (or will soon be) 1506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * blocked (via park), so the current node must 1516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * unpark its successor when it releases or 1526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * cancels. To avoid races, acquire methods must 1536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * first indicate they need a signal, 1546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * then retry the atomic acquire, and then, 1556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * on failure, block. 1566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * CANCELLED: This node is cancelled due to timeout or interrupt. 1576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Nodes never leave this state. In particular, 1586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * a thread with cancelled node never again blocks. 1596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * CONDITION: This node is currently on a condition queue. 1606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * It will not be used as a sync queue node 1616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * until transferred, at which time the status 1626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * will be set to 0. (Use of this value here has 1636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * nothing to do with the other uses of the 1646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * field, but simplifies mechanics.) 1656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * PROPAGATE: A releaseShared should be propagated to other 1666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * nodes. This is set (for head node only) in 1676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * doReleaseShared to ensure propagation 1686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * continues, even if other operations have 1696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * since intervened. 1706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 0: None of the above 1716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The values are arranged numerically to simplify use. 1736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Non-negative values mean that a node doesn't need to 1746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * signal. So, most code doesn't need to check for particular 1756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * values, just for sign. 1766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 1776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The field is initialized to 0 for normal sync nodes, and 1786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * CONDITION for condition nodes. It is modified using CAS 1796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * (or when possible, unconditional volatile writes). 1806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 1816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson volatile int waitStatus; 1826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 1846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Link to predecessor node that current node/thread relies on 18591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * for checking waitStatus. Assigned during enqueuing, and nulled 1866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * out (for sake of GC) only upon dequeuing. Also, upon 1876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * cancellation of a predecessor, we short-circuit while 1886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * finding a non-cancelled one, which will always exist 1896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * because the head node is never cancelled: A node becomes 1906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * head only as a result of successful acquire. A 1916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * cancelled thread never succeeds in acquiring, and a thread only 1926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * cancels itself, not any other node. 1936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 1946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson volatile Node prev; 1956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 1966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 1976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Link to the successor node that the current node/thread 1986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * unparks upon release. Assigned during enqueuing, adjusted 1996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * when bypassing cancelled predecessors, and nulled out (for 2006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * sake of GC) when dequeued. The enq operation does not 2016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * assign next field of a predecessor until after attachment, 2026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * so seeing a null next field does not necessarily mean that 2036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * node is at end of queue. However, if a next field appears 2046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to be null, we can scan prev's from the tail to 2056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * double-check. The next field of cancelled nodes is set to 2066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * point to the node itself instead of null, to make life 2076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * easier for isOnSyncQueue. 2086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson volatile Node next; 2106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 2126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The thread that enqueued this node. Initialized on 2136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * construction and nulled out after use. 2146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson volatile Thread thread; 2166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 2186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Link to next node waiting on condition, or the special 2196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * value SHARED. Because condition queues are accessed only 2206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * when holding in exclusive mode, we just need a simple 2216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * linked queue to hold nodes while they are waiting on 2226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * conditions. They are then transferred to the queue to 2236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * re-acquire. And because conditions can only be exclusive, 2246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * we save a field by using special value to indicate shared 2256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * mode. 2266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node nextWaiter; 2286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 23091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return true if node is waiting in shared mode 2316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final boolean isShared() { 2336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return nextWaiter == SHARED; 2346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 2376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns previous node, or throws NullPointerException if null. 2386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Use when predecessor cannot be null. The null check could 2396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * be elided, but is present to help the VM. 2406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 2416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the predecessor of this node 2426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node predecessor() throws NullPointerException { 2446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node p = prev; 2456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p == null) 2466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new NullPointerException(); 2476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else 2486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return p; 2496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node() { // Used to establish initial head or SHARED marker 2526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node(Thread thread, Node mode) { // Used by addWaiter 2556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson this.nextWaiter = mode; 2566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson this.thread = thread; 2576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node(Thread thread, int waitStatus) { // Used by Condition 2606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson this.waitStatus = waitStatus; 2616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson this.thread = thread; 2626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 2666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Head of the wait queue, lazily initialized. Except for 2676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * initialization, it is modified only via method setHead. Note: 2686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * If head exists, its waitStatus is guaranteed not to be 2696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * CANCELLED. 2706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private transient volatile Node head; 2726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 2746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Tail of the wait queue, lazily initialized. Modified only via 2756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * method enq to add new wait node. 2766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private transient volatile Node tail; 2786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 2806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The synchronization state. 2816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private volatile long state; 2836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 2856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns the current value of synchronization state. 28691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * This operation has memory semantics of a {@code volatile} read. 2876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return current state value 2886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected final long getState() { 2906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return state; 2916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 2926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 2936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 2946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Sets the value of synchronization state. 29591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * This operation has memory semantics of a {@code volatile} write. 2966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param newState the new state value 2976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 2986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected final void setState(long newState) { 2996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson state = newState; 3006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 3036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Atomically sets synchronization state to the given updated 3046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * value if the current state value equals the expected value. 30591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * This operation has memory semantics of a {@code volatile} read 3066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and write. 3076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 3086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param expect the expected value 3096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param update the new value 3106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return true if successful. False return indicates that the actual 3116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * value was not equal to the expected value. 3126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected final boolean compareAndSetState(long expect, long update) { 3146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // See below for intrinsics setup to support this 3156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return unsafe.compareAndSwapLong(this, stateOffset, expect, update); 3166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Queuing utilities 3196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 3216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The number of nanoseconds for which it is faster to spin 3226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * rather than to use timed park. A rough estimate suffices 3236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to improve responsiveness with very short timeouts. 3246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static final long spinForTimeoutThreshold = 1000L; 3266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 3286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Inserts node into queue, initializing if necessary. See picture above. 3296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the node to insert 3306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return node's predecessor 3316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private Node enq(final Node node) { 3336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 3346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node t = tail; 3356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t == null) { // Must initialize 3366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (compareAndSetHead(new Node())) 3376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson tail = head; 3386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } else { 3396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.prev = t; 3406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (compareAndSetTail(t, node)) { 3416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson t.next = node; 3426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return t; 3436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 3496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Creates and enqueues node for current thread and given mode. 3506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 3516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param mode Node.EXCLUSIVE for exclusive, Node.SHARED for shared 3526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the new node 3536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private Node addWaiter(Node mode) { 3556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node node = new Node(Thread.currentThread(), mode); 3566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Try the fast path of enq; backup to full enq on failure 3576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node pred = tail; 3586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (pred != null) { 3596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.prev = pred; 3606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (compareAndSetTail(pred, node)) { 3616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson pred.next = node; 3626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return node; 3636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson enq(node); 3666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return node; 3676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 3706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Sets head of queue to be node, thus dequeuing. Called only by 3716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * acquire methods. Also nulls out unused fields for sake of GC 3726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and to suppress unnecessary signals and traversals. 3736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 3746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the node 3756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void setHead(Node node) { 3776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson head = node; 3786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.thread = null; 3796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.prev = null; 3806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 3816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 3836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Wakes up node's successor, if one exists. 3846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 3856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the node 3866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void unparkSuccessor(Node node) { 3886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 3896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * If status is negative (i.e., possibly needing signal) try 3906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to clear in anticipation of signalling. It is OK if this 3916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * fails or if status is changed by waiting thread. 3926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 3936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int ws = node.waitStatus; 3946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (ws < 0) 3956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson compareAndSetWaitStatus(node, ws, 0); 3966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 3976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 3986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Thread to unpark is held in successor, which is normally 3996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * just the next node. But if cancelled or apparently null, 4006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * traverse backwards from tail to find the actual 4016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * non-cancelled successor. 4026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 4036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node s = node.next; 4046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (s == null || s.waitStatus > 0) { 4056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson s = null; 4066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node t = tail; t != null && t != node; t = t.prev) 4076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t.waitStatus <= 0) 4086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson s = t; 4096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (s != null) 4116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson LockSupport.unpark(s.thread); 4126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 41591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Release action for shared mode -- signals successor and ensures 4166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * propagation. (Note: For exclusive mode, release just amounts 4176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to calling unparkSuccessor of head if it needs signal.) 4186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 4196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void doReleaseShared() { 4206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 4216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Ensure that a release propagates, even if there are other 4226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * in-progress acquires/releases. This proceeds in the usual 4236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * way of trying to unparkSuccessor of head if it needs 4246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * signal. But if it does not, status is set to PROPAGATE to 4256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * ensure that upon release, propagation continues. 4266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Additionally, we must loop in case a new node is added 4276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * while we are doing this. Also, unlike other uses of 4286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * unparkSuccessor, we need to know if CAS to reset status 4296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * fails, if so rechecking. 4306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 4316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 4326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node h = head; 4336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (h != null && h != tail) { 4346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int ws = h.waitStatus; 4356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (ws == Node.SIGNAL) { 4366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!compareAndSetWaitStatus(h, Node.SIGNAL, 0)) 4376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson continue; // loop to recheck cases 4386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unparkSuccessor(h); 4396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else if (ws == 0 && 4416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson !compareAndSetWaitStatus(h, 0, Node.PROPAGATE)) 4426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson continue; // loop on failed CAS 4436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (h == head) // loop if head changed 4456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 4466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 4506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Sets head of queue, and checks if successor may be waiting 4516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * in shared mode, if so propagating if either propagate > 0 or 4526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * PROPAGATE status was set. 4536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 4546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the node 4556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param propagate the return value from a tryAcquireShared 4566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 4576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void setHeadAndPropagate(Node node, long propagate) { 4586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node h = head; // Record old head for check below 4596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson setHead(node); 4606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 4616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Try to signal next queued node if: 4626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Propagation was indicated by caller, 4636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * or was recorded (as h.waitStatus) by a previous operation 4646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * (note: this uses sign-check of waitStatus because 4656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * PROPAGATE status may transition to SIGNAL.) 4666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and 4676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The next node is waiting in shared mode, 4686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * or we don't know, because it appears null 4696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 4706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The conservatism in both of these checks may cause 4716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * unnecessary wake-ups, but only when there are multiple 4726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * racing acquires/releases, so most need signals now or soon 4736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * anyway. 4746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 4756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (propagate > 0 || h == null || h.waitStatus < 0) { 4766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node s = node.next; 4776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (s == null || s.isShared()) 4786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson doReleaseShared(); 4796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 4816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Utilities for various versions of acquire 4836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 4856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Cancels an ongoing attempt to acquire. 4866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 4876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the node 4886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 4896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void cancelAcquire(Node node) { 4906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Ignore if node doesn't exist 4916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (node == null) 4926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 4936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.thread = null; 4956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 4966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Skip cancelled predecessors 4976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node pred = node.prev; 4986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (pred.waitStatus > 0) 4996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.prev = pred = pred.prev; 5006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // predNext is the apparent node to unsplice. CASes below will 5026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // fail if not, in which case, we lost race vs another cancel 5036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // or signal, so no further action is necessary. 5046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node predNext = pred.next; 5056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Can use unconditional write instead of CAS here. 5076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // After this atomic step, other Nodes can skip past us. 5086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Before, we are free of interference from other threads. 5096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.waitStatus = Node.CANCELLED; 5106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // If we are the tail, remove ourselves. 5126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (node == tail && compareAndSetTail(node, pred)) { 5136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson compareAndSetNext(pred, predNext, null); 5146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } else { 5156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // If successor needs signal, try to set pred's next-link 5166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // so it will get one. Otherwise wake it up to propagate. 5176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int ws; 5186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (pred != head && 5196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ((ws = pred.waitStatus) == Node.SIGNAL || 5206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (ws <= 0 && compareAndSetWaitStatus(pred, ws, Node.SIGNAL))) && 5216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson pred.thread != null) { 5226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node next = node.next; 5236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (next != null && next.waitStatus <= 0) 5246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson compareAndSetNext(pred, predNext, next); 5256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } else { 5266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unparkSuccessor(node); 5276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.next = node; // help GC 5306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 5346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Checks and updates status for a node that failed to acquire. 5356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns true if thread should block. This is the main signal 53691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * control in all acquire loops. Requires that pred == node.prev. 5376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 5386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param pred node's predecessor holding status 5396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the node 5406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if thread should block 5416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 5426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static boolean shouldParkAfterFailedAcquire(Node pred, Node node) { 5436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int ws = pred.waitStatus; 5446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (ws == Node.SIGNAL) 5456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 5466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * This node has already set status asking a release 5476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to signal it, so it can safely park. 5486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 5496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 5506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (ws > 0) { 5516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 5526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Predecessor was cancelled. Skip over predecessors and 5536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * indicate retry. 5546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 5556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson do { 5566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.prev = pred = pred.prev; 5576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } while (pred.waitStatus > 0); 5586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson pred.next = node; 5596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } else { 5606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 5616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * waitStatus must be 0 or PROPAGATE. Indicate that we 5626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * need a signal, but don't park yet. Caller will need to 5636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * retry to make sure it cannot acquire before parking. 5646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 5656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson compareAndSetWaitStatus(pred, ws, Node.SIGNAL); 5666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 5686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 5716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Convenience method to interrupt current thread. 5726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 573a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson static void selfInterrupt() { 5746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Thread.currentThread().interrupt(); 5756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 5786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Convenience method to park and then check if interrupted 5796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 5806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if interrupted 5816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 5826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private final boolean parkAndCheckInterrupt() { 5836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson LockSupport.park(this); 5846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return Thread.interrupted(); 5856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 5866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 5886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Various flavors of acquire, varying in exclusive/shared and 5896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * control modes. Each is mostly the same, but annoyingly 5906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * different. Only a little bit of factoring is possible due to 5916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * interactions of exception mechanics (including ensuring that we 5926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * cancel if tryAcquire throws exception) and other control, at 5936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * least not without hurting performance too much. 5946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 5956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 5966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 5976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in exclusive uninterruptible mode for thread already in 5986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * queue. Used by condition wait methods as well as acquire. 5996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 6006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the node 6016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument 6026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if interrupted while waiting 6036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 6046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final boolean acquireQueued(final Node node, long arg) { 6056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean failed = true; 6066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson try { 6076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean interrupted = false; 6086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 6096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node p = node.predecessor(); 6106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p == head && tryAcquire(arg)) { 6116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson setHead(node); 6126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p.next = null; // help GC 6136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson failed = false; 6146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return interrupted; 6156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (shouldParkAfterFailedAcquire(p, node) && 6176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson parkAndCheckInterrupt()) 6186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson interrupted = true; 6196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } finally { 6216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (failed) 6226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson cancelAcquire(node); 6236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 6276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in exclusive interruptible mode. 6286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument 6296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 6306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void doAcquireInterruptibly(long arg) 6316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throws InterruptedException { 6326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node node = addWaiter(Node.EXCLUSIVE); 6336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean failed = true; 6346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson try { 6356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 6366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node p = node.predecessor(); 6376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p == head && tryAcquire(arg)) { 6386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson setHead(node); 6396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p.next = null; // help GC 6406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson failed = false; 6416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 6426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (shouldParkAfterFailedAcquire(p, node) && 6446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson parkAndCheckInterrupt()) 6456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 6466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } finally { 6486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (failed) 6496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson cancelAcquire(node); 6506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 6546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in exclusive timed mode. 6556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 6566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument 6576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param nanosTimeout max wait time 6586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if acquired 6596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 6606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private boolean doAcquireNanos(long arg, long nanosTimeout) 66191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle throws InterruptedException { 66291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle if (nanosTimeout <= 0L) 66391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle return false; 66491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final long deadline = System.nanoTime() + nanosTimeout; 6656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node node = addWaiter(Node.EXCLUSIVE); 6666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean failed = true; 6676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson try { 6686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 6696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node p = node.predecessor(); 6706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p == head && tryAcquire(arg)) { 6716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson setHead(node); 6726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p.next = null; // help GC 6736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson failed = false; 6746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 6756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 67691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle nanosTimeout = deadline - System.nanoTime(); 67791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle if (nanosTimeout <= 0L) 6786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 6796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (shouldParkAfterFailedAcquire(p, node) && 6806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson nanosTimeout > spinForTimeoutThreshold) 6816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson LockSupport.parkNanos(this, nanosTimeout); 6826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 6836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 6846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } finally { 6866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (failed) 6876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson cancelAcquire(node); 6886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 6906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 6916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 6926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in shared uninterruptible mode. 6936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument 6946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 6956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void doAcquireShared(long arg) { 6966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node node = addWaiter(Node.SHARED); 6976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean failed = true; 6986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson try { 6996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean interrupted = false; 7006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 7016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node p = node.predecessor(); 7026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p == head) { 7036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long r = tryAcquireShared(arg); 7046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (r >= 0) { 7056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson setHeadAndPropagate(node, r); 7066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p.next = null; // help GC 7076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (interrupted) 7086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson selfInterrupt(); 7096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson failed = false; 7106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 7116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (shouldParkAfterFailedAcquire(p, node) && 7146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson parkAndCheckInterrupt()) 7156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson interrupted = true; 7166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } finally { 7186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (failed) 7196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson cancelAcquire(node); 7206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 7246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in shared interruptible mode. 7256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument 7266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 7276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void doAcquireSharedInterruptibly(long arg) 7286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throws InterruptedException { 7296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node node = addWaiter(Node.SHARED); 7306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean failed = true; 7316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson try { 7326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 7336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node p = node.predecessor(); 7346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p == head) { 7356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long r = tryAcquireShared(arg); 7366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (r >= 0) { 7376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson setHeadAndPropagate(node, r); 7386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p.next = null; // help GC 7396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson failed = false; 7406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return; 7416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (shouldParkAfterFailedAcquire(p, node) && 7446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson parkAndCheckInterrupt()) 7456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 7466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } finally { 7486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (failed) 7496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson cancelAcquire(node); 7506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 7546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in shared timed mode. 7556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 7566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument 7576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param nanosTimeout max wait time 7586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if acquired 7596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 7606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private boolean doAcquireSharedNanos(long arg, long nanosTimeout) 76191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle throws InterruptedException { 76291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle if (nanosTimeout <= 0L) 76391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle return false; 76491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final long deadline = System.nanoTime() + nanosTimeout; 7656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node node = addWaiter(Node.SHARED); 7666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean failed = true; 7676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson try { 7686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 7696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final Node p = node.predecessor(); 7706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p == head) { 7716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long r = tryAcquireShared(arg); 7726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (r >= 0) { 7736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson setHeadAndPropagate(node, r); 7746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson p.next = null; // help GC 7756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson failed = false; 7766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 7776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 77991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle nanosTimeout = deadline - System.nanoTime(); 78091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle if (nanosTimeout <= 0L) 7816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 7826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (shouldParkAfterFailedAcquire(p, node) && 7836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson nanosTimeout > spinForTimeoutThreshold) 7846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson LockSupport.parkNanos(this, nanosTimeout); 7856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 7866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 7876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } finally { 7896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (failed) 7906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson cancelAcquire(node); 7916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 7936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Main exported methods 7956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 7966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 7976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Attempts to acquire in exclusive mode. This method should query 7986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * if the state of the object permits it to be acquired in the 7996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * exclusive mode, and if so to acquire it. 8006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>This method is always invoked by the thread performing 8026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * acquire. If this method reports failure, the acquire method 8036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * may queue the thread, if it is not already queued, until it is 8046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * signalled by a release from some other thread. This can be used 8056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to implement method {@link Lock#tryLock()}. 8066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>The default 8086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * implementation throws {@link UnsupportedOperationException}. 8096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument. This value is always the one 8116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * passed to an acquire method, or is the value saved on entry 8126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to a condition wait. The value is otherwise uninterpreted 8136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and can represent anything you like. 8146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if successful. Upon success, this object has 8156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * been acquired. 8166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if acquiring would place this 8176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * synchronizer in an illegal state. This exception must be 8186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * thrown in a consistent fashion for synchronization to work 8196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * correctly. 8206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws UnsupportedOperationException if exclusive mode is not supported 8216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 8226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected boolean tryAcquire(long arg) { 8236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new UnsupportedOperationException(); 8246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 8276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Attempts to set the state to reflect a release in exclusive 8286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * mode. 8296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>This method is always invoked by the thread performing release. 8316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>The default implementation throws 8336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link UnsupportedOperationException}. 8346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the release argument. This value is always the one 8366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * passed to a release method, or the current state value upon 8376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * entry to a condition wait. The value is otherwise 8386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * uninterpreted and can represent anything you like. 8396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if this object is now in a fully released 8406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * state, so that any waiting threads may attempt to acquire; 8416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and {@code false} otherwise. 8426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if releasing would place this 8436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * synchronizer in an illegal state. This exception must be 8446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * thrown in a consistent fashion for synchronization to work 8456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * correctly. 8466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws UnsupportedOperationException if exclusive mode is not supported 8476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 8486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected boolean tryRelease(long arg) { 8496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new UnsupportedOperationException(); 8506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 8536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Attempts to acquire in shared mode. This method should query if 8546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the state of the object permits it to be acquired in the shared 8556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * mode, and if so to acquire it. 8566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>This method is always invoked by the thread performing 8586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * acquire. If this method reports failure, the acquire method 8596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * may queue the thread, if it is not already queued, until it is 8606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * signalled by a release from some other thread. 8616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>The default implementation throws {@link 8636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * UnsupportedOperationException}. 8646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument. This value is always the one 8666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * passed to an acquire method, or is the value saved on entry 8676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to a condition wait. The value is otherwise uninterpreted 8686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and can represent anything you like. 8696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return a negative value on failure; zero if acquisition in shared 8706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * mode succeeded but no subsequent shared-mode acquire can 8716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * succeed; and a positive value if acquisition in shared 8726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * mode succeeded and subsequent shared-mode acquires might 8736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * also succeed, in which case a subsequent waiting thread 8746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * must check availability. (Support for three different 8756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * return values enables this method to be used in contexts 8766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * where acquires only sometimes act exclusively.) Upon 8776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * success, this object has been acquired. 8786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if acquiring would place this 8796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * synchronizer in an illegal state. This exception must be 8806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * thrown in a consistent fashion for synchronization to work 8816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * correctly. 8826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws UnsupportedOperationException if shared mode is not supported 8836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 8846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected long tryAcquireShared(long arg) { 8856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new UnsupportedOperationException(); 8866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 8876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 8886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 8896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Attempts to set the state to reflect a release in shared mode. 8906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>This method is always invoked by the thread performing release. 8926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>The default implementation throws 8946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link UnsupportedOperationException}. 8956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 8966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the release argument. This value is always the one 8976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * passed to a release method, or the current state value upon 8986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * entry to a condition wait. The value is otherwise 8996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * uninterpreted and can represent anything you like. 9006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if this release of shared mode may permit a 9016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * waiting acquire (shared or exclusive) to succeed; and 9026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@code false} otherwise 9036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if releasing would place this 9046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * synchronizer in an illegal state. This exception must be 9056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * thrown in a consistent fashion for synchronization to work 9066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * correctly. 9076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws UnsupportedOperationException if shared mode is not supported 9086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected boolean tryReleaseShared(long arg) { 9106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new UnsupportedOperationException(); 9116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 9146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns {@code true} if synchronization is held exclusively with 9156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * respect to the current (calling) thread. This method is invoked 9166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * upon each call to a non-waiting {@link ConditionObject} method. 9176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * (Waiting methods instead invoke {@link #release}.) 9186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 9196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>The default implementation throws {@link 9206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * UnsupportedOperationException}. This method is invoked 9216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * internally only within {@link ConditionObject} methods, so need 9226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * not be defined if conditions are not used. 9236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 9246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if synchronization is held exclusively; 9256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@code false} otherwise 9266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws UnsupportedOperationException if conditions are not supported 9276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected boolean isHeldExclusively() { 9296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new UnsupportedOperationException(); 9306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 9336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in exclusive mode, ignoring interrupts. Implemented 9346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * by invoking at least once {@link #tryAcquire}, 9356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returning on success. Otherwise the thread is queued, possibly 9366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * repeatedly blocking and unblocking, invoking {@link 9376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * #tryAcquire} until success. This method can be used 9386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to implement method {@link Lock#lock}. 9396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 9406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument. This value is conveyed to 9416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #tryAcquire} but is otherwise uninterpreted and 9426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * can represent anything you like. 9436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final void acquire(long arg) { 9456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!tryAcquire(arg) && 9466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson acquireQueued(addWaiter(Node.EXCLUSIVE), arg)) 9476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson selfInterrupt(); 9486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 9516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in exclusive mode, aborting if interrupted. 9526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Implemented by first checking interrupt status, then invoking 9536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * at least once {@link #tryAcquire}, returning on 9546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * success. Otherwise the thread is queued, possibly repeatedly 9556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * blocking and unblocking, invoking {@link #tryAcquire} 9566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * until success or the thread is interrupted. This method can be 9576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * used to implement method {@link Lock#lockInterruptibly}. 9586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 9596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument. This value is conveyed to 9606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #tryAcquire} but is otherwise uninterpreted and 9616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * can represent anything you like. 9626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws InterruptedException if the current thread is interrupted 9636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9648eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public final void acquireInterruptibly(long arg) 9658eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson throws InterruptedException { 9666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 9676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 9686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!tryAcquire(arg)) 9696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson doAcquireInterruptibly(arg); 9706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 9736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Attempts to acquire in exclusive mode, aborting if interrupted, 9746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and failing if the given timeout elapses. Implemented by first 9756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * checking interrupt status, then invoking at least once {@link 9766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * #tryAcquire}, returning on success. Otherwise, the thread is 9776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * queued, possibly repeatedly blocking and unblocking, invoking 9786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #tryAcquire} until success or the thread is interrupted 9796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * or the timeout elapses. This method can be used to implement 9806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * method {@link Lock#tryLock(long, TimeUnit)}. 9816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 9826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument. This value is conveyed to 9836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #tryAcquire} but is otherwise uninterpreted and 9846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * can represent anything you like. 9856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param nanosTimeout the maximum number of nanoseconds to wait 9866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if acquired; {@code false} if timed out 9876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws InterruptedException if the current thread is interrupted 9886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 9898eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public final boolean tryAcquireNanos(long arg, long nanosTimeout) 9908eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson throws InterruptedException { 9916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 9926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 9936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return tryAcquire(arg) || 9946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson doAcquireNanos(arg, nanosTimeout); 9956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 9966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 9976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 9986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Releases in exclusive mode. Implemented by unblocking one or 9996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * more threads if {@link #tryRelease} returns true. 10006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * This method can be used to implement method {@link Lock#unlock}. 10016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 10026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the release argument. This value is conveyed to 10036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #tryRelease} but is otherwise uninterpreted and 10046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * can represent anything you like. 10056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the value returned from {@link #tryRelease} 10066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final boolean release(long arg) { 10086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (tryRelease(arg)) { 10096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node h = head; 10106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (h != null && h.waitStatus != 0) 10116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unparkSuccessor(h); 10126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 10136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 10156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 10186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in shared mode, ignoring interrupts. Implemented by 10196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * first invoking at least once {@link #tryAcquireShared}, 10206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returning on success. Otherwise the thread is queued, possibly 10216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * repeatedly blocking and unblocking, invoking {@link 10226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * #tryAcquireShared} until success. 10236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 10246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument. This value is conveyed to 10256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #tryAcquireShared} but is otherwise uninterpreted 10266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and can represent anything you like. 10276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final void acquireShared(long arg) { 10296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (tryAcquireShared(arg) < 0) 10306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson doAcquireShared(arg); 10316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 10346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Acquires in shared mode, aborting if interrupted. Implemented 10356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * by first checking interrupt status, then invoking at least once 10366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #tryAcquireShared}, returning on success. Otherwise the 10376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * thread is queued, possibly repeatedly blocking and unblocking, 10386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * invoking {@link #tryAcquireShared} until success or the thread 10396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is interrupted. 104091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @param arg the acquire argument. 10416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * This value is conveyed to {@link #tryAcquireShared} but is 10426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * otherwise uninterpreted and can represent anything 10436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * you like. 10446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws InterruptedException if the current thread is interrupted 10456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public final void acquireSharedInterruptibly(long arg) 10478eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson throws InterruptedException { 10486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 10496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 10506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (tryAcquireShared(arg) < 0) 10516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson doAcquireSharedInterruptibly(arg); 10526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 10556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Attempts to acquire in shared mode, aborting if interrupted, and 10566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * failing if the given timeout elapses. Implemented by first 10576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * checking interrupt status, then invoking at least once {@link 10586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * #tryAcquireShared}, returning on success. Otherwise, the 10596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * thread is queued, possibly repeatedly blocking and unblocking, 10606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * invoking {@link #tryAcquireShared} until success or the thread 10616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is interrupted or the timeout elapses. 10626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 10636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the acquire argument. This value is conveyed to 10646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #tryAcquireShared} but is otherwise uninterpreted 10656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and can represent anything you like. 10666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param nanosTimeout the maximum number of nanoseconds to wait 10676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if acquired; {@code false} if timed out 10686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws InterruptedException if the current thread is interrupted 10696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10708eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public final boolean tryAcquireSharedNanos(long arg, long nanosTimeout) 10718eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson throws InterruptedException { 10726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 10736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 10746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return tryAcquireShared(arg) >= 0 || 10756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson doAcquireSharedNanos(arg, nanosTimeout); 10766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 10796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Releases in shared mode. Implemented by unblocking one or more 10806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * threads if {@link #tryReleaseShared} returns true. 10816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 10826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param arg the release argument. This value is conveyed to 10836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #tryReleaseShared} but is otherwise uninterpreted 10846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and can represent anything you like. 10856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the value returned from {@link #tryReleaseShared} 10866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 10876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final boolean releaseShared(long arg) { 10886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (tryReleaseShared(arg)) { 10896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson doReleaseShared(); 10906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 10916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 10936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 10946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Queue inspection methods 10966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 10976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 10986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Queries whether any threads are waiting to acquire. Note that 10996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * because cancellations due to interrupts and timeouts may occur 11006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * at any time, a {@code true} return does not guarantee that any 11016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * other thread will ever acquire. 11026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>In this implementation, this operation returns in 11046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * constant time. 11056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if there may be other threads waiting to acquire 11076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final boolean hasQueuedThreads() { 11096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return head != tail; 11106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 11116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 11126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 11136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Queries whether any threads have ever contended to acquire this 11146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * synchronizer; that is if an acquire method has ever blocked. 11156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>In this implementation, this operation returns in 11176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * constant time. 11186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if there has ever been contention 11206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final boolean hasContended() { 11226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return head != null; 11236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 11246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 11256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 11266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns the first (longest-waiting) thread in the queue, or 11276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@code null} if no threads are currently queued. 11286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>In this implementation, this operation normally returns in 11306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * constant time, but may iterate upon contention if other threads are 11316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * concurrently modifying the queue. 11326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the first (longest-waiting) thread in the queue, or 11346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@code null} if no threads are currently queued 11356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final Thread getFirstQueuedThread() { 11376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // handle only fast path, else relay 11386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return (head == tail) ? null : fullGetFirstQueuedThread(); 11396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 11406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 11416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 11426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Version of getFirstQueuedThread called when fastpath fails 11436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private Thread fullGetFirstQueuedThread() { 11456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 11466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The first node is normally head.next. Try to get its 11476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * thread field, ensuring consistent reads: If thread 11486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * field is nulled out or s.prev is no longer head, then 11496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * some other thread(s) concurrently performed setHead in 11506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * between some of our reads. We try this twice before 11516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * resorting to traversal. 11526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node h, s; 11546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Thread st; 11556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (((h = head) != null && (s = h.next) != null && 11566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson s.prev == head && (st = s.thread) != null) || 11576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ((h = head) != null && (s = h.next) != null && 11586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson s.prev == head && (st = s.thread) != null)) 11596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return st; 11606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 11616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 11626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Head's next field might not have been set yet, or may have 11636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * been unset after setHead. So we must check to see if tail 11646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is actually first node. If not, we continue on, safely 11656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * traversing from tail back to head to find first, 11666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * guaranteeing termination. 11676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 11696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node t = tail; 11706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Thread firstThread = null; 11716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (t != null && t != head) { 11726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Thread tt = t.thread; 11736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (tt != null) 11746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson firstThread = tt; 11756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson t = t.prev; 11766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 11776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return firstThread; 11786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 11796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 11806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 11816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns true if the given thread is currently queued. 11826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>This implementation traverses the queue to determine 11846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * presence of the given thread. 11856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 11866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param thread the thread 11876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if the given thread is on the queue 11886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NullPointerException if the thread is null 11896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 11906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final boolean isQueued(Thread thread) { 11916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (thread == null) 11926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new NullPointerException(); 11936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node p = tail; p != null; p = p.prev) 11946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.thread == thread) 11956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 11966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 11976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 11986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 11996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 12006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns {@code true} if the apparent first queued thread, if one 12016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * exists, is waiting in exclusive mode. If this method returns 12026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@code true}, and the current thread is attempting to acquire in 12036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * shared mode (that is, this method is invoked from {@link 12046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * #tryAcquireShared}) then it is guaranteed that the current thread 12056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is not the first queued thread. Used only as a heuristic in 12066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * ReentrantReadWriteLock. 12076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 12086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final boolean apparentlyFirstQueuedIsExclusive() { 12096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node h, s; 12106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return (h = head) != null && 12116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (s = h.next) != null && 12126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson !s.isShared() && 12136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson s.thread != null; 12146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 12156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 12166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 12176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Queries whether any threads have been waiting to acquire longer 12186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * than the current thread. 12196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>An invocation of this method is equivalent to (but may be 12216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * more efficient than): 12226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <pre> {@code 12236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * getFirstQueuedThread() != Thread.currentThread() && 12246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * hasQueuedThreads()}</pre> 12256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>Note that because cancellations due to interrupts and 12276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * timeouts may occur at any time, a {@code true} return does not 12286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * guarantee that some other thread will acquire before the current 12296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * thread. Likewise, it is possible for another thread to win a 12306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * race to enqueue after this method has returned {@code false}, 12316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * due to the queue being empty. 12326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>This method is designed to be used by a fair synchronizer to 1234a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * avoid <a href="AbstractQueuedSynchronizer.html#barging">barging</a>. 12356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Such a synchronizer's {@link #tryAcquire} method should return 12366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@code false}, and its {@link #tryAcquireShared} method should 12376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * return a negative value, if this method returns {@code true} 12386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * (unless this is a reentrant acquire). For example, the {@code 12396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * tryAcquire} method for a fair, reentrant, exclusive mode 12406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * synchronizer might look like this: 12416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <pre> {@code 12436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * protected boolean tryAcquire(int arg) { 12446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * if (isHeldExclusively()) { 12456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * // A reentrant acquire; increment hold count 12466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * return true; 12476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * } else if (hasQueuedPredecessors()) { 12486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * return false; 12496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * } else { 12506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * // try to acquire normally 12516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * } 12526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * }}</pre> 12536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if there is a queued thread preceding the 12556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * current thread, and {@code false} if the current thread 12566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is at the head of the queue or the queue is empty 12576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @since 1.7 12586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 125991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle public final boolean hasQueuedPredecessors() { 12606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // The correctness of this depends on head being initialized 12616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // before tail and on head.next being accurate if the current 12626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // thread is first in queue. 12636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node t = tail; // Read fields in reverse initialization order 12646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node h = head; 12656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node s; 12666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return h != t && 12676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ((s = h.next) == null || s.thread != Thread.currentThread()); 12686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 12696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 12706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 12716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Instrumentation and monitoring methods 12726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 12736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 12746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns an estimate of the number of threads waiting to 12756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * acquire. The value is only an estimate because the number of 12766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * threads may change dynamically while this method traverses 12776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * internal data structures. This method is designed for use in 12786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * monitoring system state, not for synchronization 12796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * control. 12806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 12816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the estimated number of threads waiting to acquire 12826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 12836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final int getQueueLength() { 12846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int n = 0; 12856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node p = tail; p != null; p = p.prev) { 12866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.thread != null) 12876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ++n; 12886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 12896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return n; 12906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 12916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 12926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 12936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns a collection containing threads that may be waiting to 12946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * acquire. Because the actual set of threads may change 12956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * dynamically while constructing this result, the returned 12966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * collection is only a best-effort estimate. The elements of the 12976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returned collection are in no particular order. This method is 12986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * designed to facilitate construction of subclasses that provide 12996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * more extensive monitoring facilities. 13006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 13016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the collection of threads 13026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final Collection<Thread> getQueuedThreads() { 13046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ArrayList<Thread> list = new ArrayList<Thread>(); 13056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node p = tail; p != null; p = p.prev) { 13066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Thread t = p.thread; 13076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t != null) 13086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson list.add(t); 13096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return list; 13116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns a collection containing threads that may be waiting to 13156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * acquire in exclusive mode. This has the same properties 13166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * as {@link #getQueuedThreads} except that it only returns 13176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * those threads waiting due to an exclusive acquire. 13186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 13196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the collection of threads 13206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final Collection<Thread> getExclusiveQueuedThreads() { 13226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ArrayList<Thread> list = new ArrayList<Thread>(); 13236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node p = tail; p != null; p = p.prev) { 13246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!p.isShared()) { 13256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Thread t = p.thread; 13266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t != null) 13276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson list.add(t); 13286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return list; 13316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns a collection containing threads that may be waiting to 13356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * acquire in shared mode. This has the same properties 13366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * as {@link #getQueuedThreads} except that it only returns 13376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * those threads waiting due to a shared acquire. 13386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 13396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the collection of threads 13406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final Collection<Thread> getSharedQueuedThreads() { 13426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ArrayList<Thread> list = new ArrayList<Thread>(); 13436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node p = tail; p != null; p = p.prev) { 13446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (p.isShared()) { 13456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Thread t = p.thread; 13466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t != null) 13476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson list.add(t); 13486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return list; 13516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns a string identifying this synchronizer, as well as its state. 13556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * The state, in brackets, includes the String {@code "State ="} 13566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * followed by the current value of {@link #getState}, and either 13576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@code "nonempty"} or {@code "empty"} depending on whether the 13586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * queue is empty. 13596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 13606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return a string identifying this synchronizer, as well as its state 13616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public String toString() { 13636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long s = getState(); 13646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson String q = hasQueuedThreads() ? "non" : ""; 13656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return super.toString() + 13666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson "[State = " + s + ", " + q + "empty queue]"; 13676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Internal support methods for Conditions 13716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns true if a node, always one that was initially placed on 13746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * a condition queue, is now waiting to reacquire on sync queue. 13756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the node 13766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return true if is reacquiring 13776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final boolean isOnSyncQueue(Node node) { 13796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (node.waitStatus == Node.CONDITION || node.prev == null) 13806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 13816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (node.next != null) // If has successor, it must be on queue 13826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 13836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 13846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * node.prev can be non-null, but not yet on queue because 13856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the CAS to place it on queue can fail. So we have to 13866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * traverse from tail to make sure it actually made it. It 13876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * will always be near the tail in calls to this method, and 13886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * unless the CAS failed (which is unlikely), it will be 13896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * there, so we hardly ever traverse much. 13906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return findNodeFromTail(node); 13926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 13936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 13946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 13956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns true if node is on sync queue by searching backwards from tail. 13966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Called only when needed by isOnSyncQueue. 13976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return true if present 13986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 13996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private boolean findNodeFromTail(Node node) { 14006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node t = tail; 14016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (;;) { 14026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t == node) 14036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 14046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t == null) 14056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 14066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson t = t.prev; 14076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 14106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 14116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Transfers a node from a condition queue onto sync queue. 14126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns true if successful. 14136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the node 14146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return true if successfully transferred (else the node was 141591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * cancelled before signal) 14166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 14176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final boolean transferForSignal(Node node) { 14186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 14196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * If cannot change waitStatus, the node has been cancelled. 14206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 14216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!compareAndSetWaitStatus(node, Node.CONDITION, 0)) 14226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 14236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 14246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 14256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Splice onto queue and try to set waitStatus of predecessor to 14266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * indicate that thread is (probably) waiting. If cancelled or 14276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * attempt to set waitStatus fails, wake up to resync (in which 14286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * case the waitStatus can be transiently and harmlessly wrong). 14296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 14306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node p = enq(node); 14316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int ws = p.waitStatus; 14326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (ws > 0 || !compareAndSetWaitStatus(p, ws, Node.SIGNAL)) 14336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson LockSupport.unpark(node.thread); 14346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 14356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 14376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 143891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Transfers node, if necessary, to sync queue after a cancelled wait. 143991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Returns true if thread was cancelled before being signalled. 144091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * 144191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @param node the node 14426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return true if cancelled before the node was signalled 14436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 14446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final boolean transferAfterCancelledWait(Node node) { 14456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (compareAndSetWaitStatus(node, Node.CONDITION, 0)) { 14466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson enq(node); 14476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 14486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 14506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * If we lost out to a signal(), then we can't proceed 14516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * until it finishes its enq(). Cancelling during an 14526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * incomplete transfer is both rare and transient, so just 14536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * spin. 14546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 14556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (!isOnSyncQueue(node)) 14566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Thread.yield(); 14576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 14586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 14606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 14616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Invokes release with current state value; returns saved state. 14626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Cancels node and throws exception on failure. 14636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param node the condition node for this wait 14646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return previous sync state 14656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 14666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final long fullyRelease(Node node) { 14676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean failed = true; 14686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson try { 14696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long savedState = getState(); 14706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (release(savedState)) { 14716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson failed = false; 14726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return savedState; 14736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } else { 14746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new IllegalMonitorStateException(); 14756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } finally { 14776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (failed) 14786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson node.waitStatus = Node.CANCELLED; 14796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 14826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Instrumentation methods for conditions 14836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 14846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 14856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Queries whether the given ConditionObject 14866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * uses this synchronizer as its lock. 14876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 14886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param condition the condition 148991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code true} if owned 14906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NullPointerException if the condition is null 14916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 14926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final boolean owns(ConditionObject condition) { 14936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return condition.isOwnedBy(this); 14946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 14956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 14966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 14976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Queries whether any threads are waiting on the given condition 14986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * associated with this synchronizer. Note that because timeouts 149991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * and interrupts may occur at any time, a {@code true} return 150091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * does not guarantee that a future {@code signal} will awaken 15016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * any threads. This method is designed primarily for use in 15026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * monitoring of the system state. 15036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 15046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param condition the condition 150591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * @return {@code true} if there are any waiting threads 15066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if exclusive synchronization 15076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is not held 15086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalArgumentException if the given condition is 15096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * not associated with this synchronizer 15106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NullPointerException if the condition is null 15116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 15126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final boolean hasWaiters(ConditionObject condition) { 15136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!owns(condition)) 15146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new IllegalArgumentException("Not owner"); 15156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return condition.hasWaiters(); 15166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 15196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns an estimate of the number of threads waiting on the 15206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * given condition associated with this synchronizer. Note that 15216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * because timeouts and interrupts may occur at any time, the 15226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * estimate serves only as an upper bound on the actual number of 15236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * waiters. This method is designed for use in monitoring of the 15246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * system state, not for synchronization control. 15256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 15266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param condition the condition 15276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the estimated number of waiting threads 15286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if exclusive synchronization 15296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is not held 15306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalArgumentException if the given condition is 15316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * not associated with this synchronizer 15326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NullPointerException if the condition is null 15336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 15346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final int getWaitQueueLength(ConditionObject condition) { 15356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!owns(condition)) 15366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new IllegalArgumentException("Not owner"); 15376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return condition.getWaitQueueLength(); 15386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 15416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns a collection containing those threads that may be 15426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * waiting on the given condition associated with this 15436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * synchronizer. Because the actual set of threads may change 15446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * dynamically while constructing this result, the returned 15456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * collection is only a best-effort estimate. The elements of the 15466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returned collection are in no particular order. 15476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 15486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param condition the condition 15496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the collection of threads 15506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if exclusive synchronization 15516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * is not held 15526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalArgumentException if the given condition is 15536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * not associated with this synchronizer 15546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws NullPointerException if the condition is null 15556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 15566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final Collection<Thread> getWaitingThreads(ConditionObject condition) { 15576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!owns(condition)) 15586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new IllegalArgumentException("Not owner"); 15596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return condition.getWaitingThreads(); 15606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 15616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 15636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Condition implementation for a {@link 15646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * AbstractQueuedLongSynchronizer} serving as the basis of a {@link 15656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Lock} implementation. 15666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 15676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>Method documentation for this class describes mechanics, 15686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * not behavioral specifications from the point of view of Lock 15696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * and Condition users. Exported versions of this class will in 15706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * general need to be accompanied by documentation describing 15716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * condition semantics that rely on those of the associated 157291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * {@code AbstractQueuedLongSynchronizer}. 15736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 15746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <p>This class is Serializable, but all fields are transient, 15756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * so deserialized conditions have no waiters. 15766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 15776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @since 1.6 15786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 15796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public class ConditionObject implements Condition, java.io.Serializable { 15806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final long serialVersionUID = 1173984872572414699L; 15816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** First node of condition queue. */ 15826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private transient Node firstWaiter; 15836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** Last node of condition queue. */ 15846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private transient Node lastWaiter; 15856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 158791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * Creates a new {@code ConditionObject} instance. 15886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 15896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public ConditionObject() { } 15906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // Internal methods 15926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 15936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 15946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Adds a new waiter to wait queue. 15956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return its new wait node 15966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 15976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private Node addConditionWaiter() { 15986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node t = lastWaiter; 15996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // If lastWaiter is cancelled, clean out. 16006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t != null && t.waitStatus != Node.CONDITION) { 16016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlinkCancelledWaiters(); 16026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson t = lastWaiter; 16036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 16046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node node = new Node(Thread.currentThread(), Node.CONDITION); 16056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t == null) 16066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson firstWaiter = node; 16076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else 16086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson t.nextWaiter = node; 16096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson lastWaiter = node; 16106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return node; 16116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 16126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 16136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 16146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Removes and transfers nodes until hit non-cancelled one or 16156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * null. Split out from signal in part to encourage compilers 16166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * to inline the case of no waiters. 16176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param first (non-null) the first node on condition queue 16186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 16196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void doSignal(Node first) { 16206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson do { 16216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if ( (firstWaiter = first.nextWaiter) == null) 16226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson lastWaiter = null; 16236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson first.nextWaiter = null; 16246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } while (!transferForSignal(first) && 16256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (first = firstWaiter) != null); 16266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 16276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 16286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 16296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Removes and transfers all nodes. 16306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @param first (non-null) the first node on condition queue 16316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 16326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void doSignalAll(Node first) { 16336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson lastWaiter = firstWaiter = null; 16346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson do { 16356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node next = first.nextWaiter; 16366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson first.nextWaiter = null; 16376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson transferForSignal(first); 16386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson first = next; 16396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } while (first != null); 16406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 16416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 16426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 16436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Unlinks cancelled waiter nodes from condition queue. 16446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Called only while holding lock. This is called when 16456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * cancellation occurred during condition wait, and upon 16466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * insertion of a new waiter when lastWaiter is seen to have 16476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * been cancelled. This method is needed to avoid garbage 16486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * retention in the absence of signals. So even though it may 16496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * require a full traversal, it comes into play only when 16506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * timeouts or cancellations occur in the absence of 16516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * signals. It traverses all nodes rather than stopping at a 16526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * particular target to unlink all pointers to garbage nodes 16536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * without requiring many re-traversals during cancellation 16546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * storms. 16556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 16566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void unlinkCancelledWaiters() { 16576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node t = firstWaiter; 16586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node trail = null; 16596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (t != null) { 16606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node next = t.nextWaiter; 16616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t.waitStatus != Node.CONDITION) { 16626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson t.nextWaiter = null; 16636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (trail == null) 16646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson firstWaiter = next; 16656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else 16666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson trail.nextWaiter = next; 16676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (next == null) 16686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson lastWaiter = trail; 16696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 16706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else 16716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson trail = t; 16726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson t = next; 16736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 16746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 16756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 16766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // public methods 16776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 16786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 16796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Moves the longest-waiting thread, if one exists, from the 16806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * wait queue for this condition to the wait queue for the 16816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * owning lock. 16826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 16836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if {@link #isHeldExclusively} 16846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returns {@code false} 16856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 16866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final void signal() { 16876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!isHeldExclusively()) 16886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new IllegalMonitorStateException(); 16896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node first = firstWaiter; 16906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (first != null) 16916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson doSignal(first); 16926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 16936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 16946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 16956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Moves all threads from the wait queue for this condition to 16966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * the wait queue for the owning lock. 16976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 16986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if {@link #isHeldExclusively} 16996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returns {@code false} 17006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 17016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final void signalAll() { 17026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!isHeldExclusively()) 17036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new IllegalMonitorStateException(); 17046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node first = firstWaiter; 17056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (first != null) 17066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson doSignalAll(first); 17076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 17086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 17096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 17106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Implements uninterruptible condition wait. 17116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <ol> 17126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Save lock state returned by {@link #getState}. 171391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * <li> Invoke {@link #release} with saved state as argument, 171491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * throwing IllegalMonitorStateException if it fails. 17156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Block until signalled. 17166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Reacquire by invoking specialized version of 17176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #acquire} with saved state as argument. 17186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * </ol> 17196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 17206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final void awaitUninterruptibly() { 17216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node node = addConditionWaiter(); 17226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long savedState = fullyRelease(node); 17236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean interrupted = false; 17246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (!isOnSyncQueue(node)) { 17256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson LockSupport.park(this); 17266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 17276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson interrupted = true; 17286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 17296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (acquireQueued(node, savedState) || interrupted) 17306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson selfInterrupt(); 17316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 17326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 17336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /* 17346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * For interruptible waits, we need to track whether to throw 17356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * InterruptedException, if interrupted while blocked on 17366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * condition, versus reinterrupt current thread, if 17376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * interrupted while blocked waiting to re-acquire. 17386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 17396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 17406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** Mode meaning to reinterrupt on exit from wait */ 17416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final int REINTERRUPT = 1; 17426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** Mode meaning to throw InterruptedException on exit from wait */ 17436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final int THROW_IE = -1; 17446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 17456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 17466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Checks for interrupt, returning THROW_IE if interrupted 17476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * before signalled, REINTERRUPT if after signalled, or 17486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 0 if not interrupted. 17496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 17506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private int checkInterruptWhileWaiting(Node node) { 17516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return Thread.interrupted() ? 17526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (transferAfterCancelledWait(node) ? THROW_IE : REINTERRUPT) : 17536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 0; 17546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 17556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 17566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 17576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Throws InterruptedException, reinterrupts current thread, or 17586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * does nothing, depending on mode. 17596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 17606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private void reportInterruptAfterWait(int interruptMode) 17616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throws InterruptedException { 17626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (interruptMode == THROW_IE) 17636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 17646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson else if (interruptMode == REINTERRUPT) 17656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson selfInterrupt(); 17666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 17676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 17686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 17696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Implements interruptible condition wait. 17706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <ol> 17716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If current thread is interrupted, throw InterruptedException. 17726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Save lock state returned by {@link #getState}. 177391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * <li> Invoke {@link #release} with saved state as argument, 177491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * throwing IllegalMonitorStateException if it fails. 17756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Block until signalled or interrupted. 17766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Reacquire by invoking specialized version of 17776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #acquire} with saved state as argument. 17786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If interrupted while blocked in step 4, throw InterruptedException. 17796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * </ol> 17806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 17816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson public final void await() throws InterruptedException { 17826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 17836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 17846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node node = addConditionWaiter(); 17856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long savedState = fullyRelease(node); 17866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int interruptMode = 0; 17876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (!isOnSyncQueue(node)) { 17886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson LockSupport.park(this); 17896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) 17906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 17916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 17926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (acquireQueued(node, savedState) && interruptMode != THROW_IE) 17936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson interruptMode = REINTERRUPT; 17946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (node.nextWaiter != null) // clean up if cancelled 17956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlinkCancelledWaiters(); 17966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (interruptMode != 0) 17976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson reportInterruptAfterWait(interruptMode); 17986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 17996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 18006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 18016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Implements timed condition wait. 18026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <ol> 18036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If current thread is interrupted, throw InterruptedException. 18046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Save lock state returned by {@link #getState}. 180591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * <li> Invoke {@link #release} with saved state as argument, 180691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * throwing IllegalMonitorStateException if it fails. 18076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Block until signalled, interrupted, or timed out. 18086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Reacquire by invoking specialized version of 18096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #acquire} with saved state as argument. 18106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If interrupted while blocked in step 4, throw InterruptedException. 18116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * </ol> 18126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 18138eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public final long awaitNanos(long nanosTimeout) 18148eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson throws InterruptedException { 18156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 18166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 18176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node node = addConditionWaiter(); 18186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long savedState = fullyRelease(node); 181991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final long deadline = System.nanoTime() + nanosTimeout; 18206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int interruptMode = 0; 18216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (!isOnSyncQueue(node)) { 18226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (nanosTimeout <= 0L) { 18236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson transferAfterCancelledWait(node); 18246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 18256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 182691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle if (nanosTimeout >= spinForTimeoutThreshold) 182791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle LockSupport.parkNanos(this, nanosTimeout); 18286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) 18296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 183091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle nanosTimeout = deadline - System.nanoTime(); 18316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 18326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (acquireQueued(node, savedState) && interruptMode != THROW_IE) 18336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson interruptMode = REINTERRUPT; 18346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (node.nextWaiter != null) 18356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlinkCancelledWaiters(); 18366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (interruptMode != 0) 18376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson reportInterruptAfterWait(interruptMode); 183891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle return deadline - System.nanoTime(); 18396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 18406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 18416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 18426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Implements absolute timed condition wait. 18436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <ol> 18446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If current thread is interrupted, throw InterruptedException. 18456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Save lock state returned by {@link #getState}. 184691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * <li> Invoke {@link #release} with saved state as argument, 184791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * throwing IllegalMonitorStateException if it fails. 18486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Block until signalled, interrupted, or timed out. 18496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Reacquire by invoking specialized version of 18506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #acquire} with saved state as argument. 18516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If interrupted while blocked in step 4, throw InterruptedException. 18526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If timed out while blocked in step 4, return false, else true. 18536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * </ol> 18546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 18558eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public final boolean awaitUntil(Date deadline) 18568eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson throws InterruptedException { 18576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long abstime = deadline.getTime(); 18586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 18596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 18606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node node = addConditionWaiter(); 18616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long savedState = fullyRelease(node); 18626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean timedout = false; 18636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int interruptMode = 0; 18646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (!isOnSyncQueue(node)) { 18656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (System.currentTimeMillis() > abstime) { 18666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson timedout = transferAfterCancelledWait(node); 18676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 18686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 18696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson LockSupport.parkUntil(this, abstime); 18706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) 18716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 18726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 18736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (acquireQueued(node, savedState) && interruptMode != THROW_IE) 18746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson interruptMode = REINTERRUPT; 18756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (node.nextWaiter != null) 18766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlinkCancelledWaiters(); 18776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (interruptMode != 0) 18786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson reportInterruptAfterWait(interruptMode); 18796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return !timedout; 18806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 18816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 18826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 18836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Implements timed condition wait. 18846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <ol> 18856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If current thread is interrupted, throw InterruptedException. 18866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Save lock state returned by {@link #getState}. 188791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * <li> Invoke {@link #release} with saved state as argument, 188891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * throwing IllegalMonitorStateException if it fails. 18896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Block until signalled, interrupted, or timed out. 18906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> Reacquire by invoking specialized version of 18916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * {@link #acquire} with saved state as argument. 18926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If interrupted while blocked in step 4, throw InterruptedException. 18936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * <li> If timed out while blocked in step 4, return false, else true. 18946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * </ol> 18956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 18968eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson public final boolean await(long time, TimeUnit unit) 18978eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson throws InterruptedException { 18986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long nanosTimeout = unit.toNanos(time); 18996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (Thread.interrupted()) 19006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new InterruptedException(); 19016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node node = addConditionWaiter(); 19026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson long savedState = fullyRelease(node); 190391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle final long deadline = System.nanoTime() + nanosTimeout; 19046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson boolean timedout = false; 19056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int interruptMode = 0; 19066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson while (!isOnSyncQueue(node)) { 19076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (nanosTimeout <= 0L) { 19086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson timedout = transferAfterCancelledWait(node); 19096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 19106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (nanosTimeout >= spinForTimeoutThreshold) 19126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson LockSupport.parkNanos(this, nanosTimeout); 19136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if ((interruptMode = checkInterruptWhileWaiting(node)) != 0) 19146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson break; 191591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle nanosTimeout = deadline - System.nanoTime(); 19166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (acquireQueued(node, savedState) && interruptMode != THROW_IE) 19186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson interruptMode = REINTERRUPT; 19196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (node.nextWaiter != null) 19206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson unlinkCancelledWaiters(); 19216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (interruptMode != 0) 19226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson reportInterruptAfterWait(interruptMode); 19236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return !timedout; 19246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 19266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson // support for instrumentation 19276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 19286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 19296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns true if this condition was created by the given 19306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * synchronization object. 19316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 19326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if owned 19336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 19346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson final boolean isOwnedBy(AbstractQueuedLongSynchronizer sync) { 19356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return sync == AbstractQueuedLongSynchronizer.this; 19366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 19386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 19396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Queries whether any threads are waiting on this condition. 19406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Implements {@link AbstractQueuedLongSynchronizer#hasWaiters}. 19416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 19426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return {@code true} if there are any waiting threads 19436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if {@link #isHeldExclusively} 19446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returns {@code false} 19456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 19466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected final boolean hasWaiters() { 19476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!isHeldExclusively()) 19486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new IllegalMonitorStateException(); 19496232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node w = firstWaiter; w != null; w = w.nextWaiter) { 19506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (w.waitStatus == Node.CONDITION) 19516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return true; 19526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return false; 19546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 19566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 19576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns an estimate of the number of threads waiting on 19586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * this condition. 19596232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Implements {@link AbstractQueuedLongSynchronizer#getWaitQueueLength}. 19606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 19616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the estimated number of waiting threads 19626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if {@link #isHeldExclusively} 19636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returns {@code false} 19646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 19656232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected final int getWaitQueueLength() { 19666232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!isHeldExclusively()) 19676232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new IllegalMonitorStateException(); 19686232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int n = 0; 19696232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node w = firstWaiter; w != null; w = w.nextWaiter) { 19706232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (w.waitStatus == Node.CONDITION) 19716232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ++n; 19726232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19736232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return n; 19746232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19756232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 19766232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 19776232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Returns a collection containing those threads that may be 19786232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * waiting on this Condition. 19796232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Implements {@link AbstractQueuedLongSynchronizer#getWaitingThreads}. 19806232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * 19816232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @return the collection of threads 19826232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * @throws IllegalMonitorStateException if {@link #isHeldExclusively} 19836232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * returns {@code false} 19846232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 19856232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson protected final Collection<Thread> getWaitingThreads() { 19866232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (!isHeldExclusively()) 19876232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson throw new IllegalMonitorStateException(); 19886232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson ArrayList<Thread> list = new ArrayList<Thread>(); 19896232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson for (Node w = firstWaiter; w != null; w = w.nextWaiter) { 19906232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (w.waitStatus == Node.CONDITION) { 19916232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Thread t = w.thread; 19926232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson if (t != null) 19936232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson list.add(t); 19946232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19956232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19966232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return list; 19976232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19986232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 19996232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 20006232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 20016232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * Setup to support compareAndSet. We need to natively implement 20026232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * this here: For the sake of permitting future enhancements, we 20036232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * cannot explicitly subclass AtomicLong, which would be 20046232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * efficient and useful otherwise. So, as the lesser of evils, we 20056232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * natively implement using hotspot intrinsics API. And while we 20066232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * are at it, we do the same for other CASable fields (which could 20076232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * otherwise be done with atomic field updaters). 20086232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 20096232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final Unsafe unsafe = Unsafe.getUnsafe(); 20106232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final long stateOffset; 20116232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final long headOffset; 20126232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final long tailOffset; 20136232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final long waitStatusOffset; 20146232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private static final long nextOffset; 20156232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 20166232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson static { 20176232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson try { 20186232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson stateOffset = unsafe.objectFieldOffset 20196232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (AbstractQueuedLongSynchronizer.class.getDeclaredField("state")); 20206232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson headOffset = unsafe.objectFieldOffset 20216232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (AbstractQueuedLongSynchronizer.class.getDeclaredField("head")); 20226232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson tailOffset = unsafe.objectFieldOffset 20236232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (AbstractQueuedLongSynchronizer.class.getDeclaredField("tail")); 20246232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson waitStatusOffset = unsafe.objectFieldOffset 20256232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (Node.class.getDeclaredField("waitStatus")); 20266232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson nextOffset = unsafe.objectFieldOffset 20276232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson (Node.class.getDeclaredField("next")); 20286232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 20296232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } catch (Exception ex) { throw new Error(ex); } 20306232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 20316232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 20326232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 20336232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * CAS head field. Used only by enq. 20346232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 20356232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private final boolean compareAndSetHead(Node update) { 20366232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return unsafe.compareAndSwapObject(this, headOffset, null, update); 20376232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 20386232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 20396232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 20406232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * CAS tail field. Used only by enq. 20416232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 20426232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson private final boolean compareAndSetTail(Node expect, Node update) { 20436232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return unsafe.compareAndSwapObject(this, tailOffset, expect, update); 20446232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 20456232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 20466232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 20476232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * CAS waitStatus field of a node. 20486232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 20498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson private static final boolean compareAndSetWaitStatus(Node node, 20506232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int expect, 20516232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson int update) { 20526232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return unsafe.compareAndSwapInt(node, waitStatusOffset, 20536232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson expect, update); 20546232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 20556232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson 20566232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson /** 20576232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson * CAS next field of a node. 20586232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson */ 20598eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson private static final boolean compareAndSetNext(Node node, 20606232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node expect, 20616232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson Node update) { 20626232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson return unsafe.compareAndSwapObject(node, nextOffset, expect, update); 20636232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson } 20646232a5efed0ea103e35aec73206e5e03a8b82e0cJesse Wilson} 2065