Home > database >  The mutex
The mutex

Time:09-23

To implement a simple mutex

AQS is what?

1233356-888 f5765bcacac1d. PNG
The reference [2],/* * * Returns a collection containing threads that may be waiting to * acquire. Because the actual set of threads may change * dynamically while constructing this result, the returned * collection is only a best - effort estimate. The elements of the * returned collection are in no particular order. This method is * designed to facilitate the construction of subclasses that dojo.provide * more extensive monitoring facilities. * * @ return the collection of threads */public final Collection GetQueuedThreads () {ArrayList list=new ArrayList (a); For (the Node p=tail; p !=null; T={p=p.p rev) Thread p.t hread; if (t !=null) list. Add (t); } the return list; }/* * * Returns a collection containing threads that may be waiting to * acquire in exclusive mode. This has the same properties as * {@ # link getQueuedThreads} the except that it only Returns * those threads waiting due to an exclusive (unique; Exclusive; Specific) acquire. * * @ return the collection of threads */public final Collection GetExclusiveQueuedThreads () {ArrayList list=new ArrayList (a); For (the Node p=tail; p !=null; P=p.p rev) {if (! P.i sShared ()) {Thread t=p.t hread; if (t !=null) list. Add (t); }} return list; } the CAS spin

Short for CAS is to Compare And Swap, with a single atomic operation characteristics of variable, exchanged contrast after a successful operation, he is optimistic the operation, during operation, the infinite loop until success, And then follow-up interactions

CAS contains three operating data, memory location V, expected value, A new expected value B, if the current V to store data and A memory, is considered more successful, then the position is set to the current V B,

If V==A (Compare)
Then V=B (Swap)
Because the infinite loop operation, so that can lead to low CPU efficiency, and can also lead to ABA in the operation of the problem, is also A - & gt; B - & gt; A problem, mistakenly assume that data does not change at this time, actually in the middle have changed, and the problems in Java provides class AtomicStampedReference solve this problem, first look at the current reference value is in line with expectations, ABA will also become A - 1 & gt; 2 b - & gt; 3 a, it's so clear perception to change,

1233356-6 ff0890cd5de5ba3. PNG
1233356 - eb505dd77563b0bd. PNG
1233356-5159104108 dc1fa4. PNG
Java. Util. Concurrent. The locks the static final class AbstractQueuedSynchronizer. Node extends Object

Wait queue node class.
The wait queue is a variant of a "CLH" (Craig, Landin, and Hagersten) lock queue. CLH locks are normally used for spinlocks(自旋锁). We instead use them for blocking synchronizers, but use the same basic tactic of holding some of the control information about a thread in the predecessor of its node. A "status" field in each node keeps track of whether a thread should block. A node is signalled when its predecessor releases. Each node of the queue otherwise serves as a specific-notification-style monitor holding a single waiting thread. The status field does NOT control whether threads are granted locks etc though. A thread may try to acquire if it is first in the queue. But being first does not guarantee success; It only gives the right to contend. So the currently released contender thread may need to rewait.
To the enqueue into a CLH lock, you atomically splice it in as the new tail. The To dequeue, you just set the head field.

1233356 - ae3c9a66b74bc0d1. PNG
Insertion into a CLH queue requires only a single atomic operation on "tail", so there is a simple atomic point of demarcation from unqueued to queued. Similarly, dequeuing involves only updating the "head". Or, it takes a bit more work for nodes to determine their successors who are, in part to deal with possible cancellation due to timeouts and interrupts.
The "prev" links (not 2 in The original CLH locks), are mainly men to handle cancellation. If a node is cancelled, its successor is (normally) relinked to a non - cancelled. Predecessor For explanation of similar mechanics in The case of spin locks, see The cca shut by Scott and Scherer at http://www.cs.rochester.edu/u/scott/synchronization/
We also use "next" links to implement blocking mechanics. The thread id for each node is kept in its own node, so a predecessor signals the next node to wake up by traversing next link to determine which thread it is. Determination of successor must avoid races with newly queued nodes to set the "next" fields of their predecessors. This is solved when necessary by checking backwards from the atomically updated "tail" when a node's successor appears to be null. (Or, said differently, the next-links are an optimization so that we don't usually need a backward scan.)
Cancellation introduces some conservatism to the basic algorithms. Since we must poll for Cancellation of other nodes, we can miss noticing been cancelled a node is ahead or behind us. This is dealt with by always unparking successors upon Cancellation, allowing them to stabilize on a new predecessor, unless we can identify the an uncancelled predecessor who will carry This responsibility.
CLH the queues need a dummy header node to get started. But we don 't create them on construction, because it whenever wasted effort if there is never contention. The home, the node is constructed and the head and tail Pointers are set upon first contention.
nullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull
  • Related