1 /*
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * This code is free software; you can redistribute it and/or modify it
5  * under the terms of the GNU General Public License version 2 only, as
6  * published by the Free Software Foundation.  Oracle designates this
7  * particular file as subject to the "Classpath" exception as provided
8  * by Oracle in the LICENSE file that accompanied this code.
9  *
10  * This code is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * version 2 for more details (a copy is included in the LICENSE file that
14  * accompanied this code).
15  *
16  * You should have received a copy of the GNU General Public License version
17  * 2 along with this work; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
19  *
20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
21  * or visit www.oracle.com if you need additional information or have any
22  * questions.
23  */
24 
25 /*
26  * This file is available under and governed by the GNU General Public
27  * License version 2 only, as published by the Free Software Foundation.
28  * However, the following notice accompanied the original version of this
29  * file:
30  *
31  * Written by Doug Lea, Bill Scherer, and Michael Scott with
32  * assistance from members of JCP JSR-166 Expert Group and released to
33  * the public domain, as explained at
34  * http://creativecommons.org/publicdomain/zero/1.0/
35  */
36 
37 package java.util.concurrent;
38 
39 import java.lang.invoke.MethodHandles;
40 import java.lang.invoke.VarHandle;
41 import java.util.concurrent.locks.LockSupport;
42 
43 /**
44  * A synchronization point at which threads can pair and swap elements
45  * within pairs.  Each thread presents some object on entry to the
46  * {@link #exchange exchange} method, matches with a partner thread,
47  * and receives its partner's object on return.  An Exchanger may be
48  * viewed as a bidirectional form of a {@link SynchronousQueue}.
49  * Exchangers may be useful in applications such as genetic algorithms
50  * and pipeline designs.
51  *
52  * <p><b>Sample Usage:</b>
53  * Here are the highlights of a class that uses an {@code Exchanger}
54  * to swap buffers between threads so that the thread filling the
55  * buffer gets a freshly emptied one when it needs it, handing off the
56  * filled one to the thread emptying the buffer.
57  * <pre> {@code
58  * class FillAndEmpty {
59  *   Exchanger<DataBuffer> exchanger = new Exchanger<>();
60  *   DataBuffer initialEmptyBuffer = ...; // a made-up type
61  *   DataBuffer initialFullBuffer = ...;
62  *
63  *   class FillingLoop implements Runnable {
64  *     public void run() {
65  *       DataBuffer currentBuffer = initialEmptyBuffer;
66  *       try {
67  *         while (currentBuffer != null) {
68  *           addToBuffer(currentBuffer);
69  *           if (currentBuffer.isFull())
70  *             currentBuffer = exchanger.exchange(currentBuffer);
71  *         }
72  *       } catch (InterruptedException ex) { ... handle ...}
73  *     }
74  *   }
75  *
76  *   class EmptyingLoop implements Runnable {
77  *     public void run() {
78  *       DataBuffer currentBuffer = initialFullBuffer;
79  *       try {
80  *         while (currentBuffer != null) {
81  *           takeFromBuffer(currentBuffer);
82  *           if (currentBuffer.isEmpty())
83  *             currentBuffer = exchanger.exchange(currentBuffer);
84  *         }
85  *       } catch (InterruptedException ex) { ... handle ...}
86  *     }
87  *   }
88  *
89  *   void start() {
90  *     new Thread(new FillingLoop()).start();
91  *     new Thread(new EmptyingLoop()).start();
92  *   }
93  * }}</pre>
94  *
95  * <p>Memory consistency effects: For each pair of threads that
96  * successfully exchange objects via an {@code Exchanger}, actions
97  * prior to the {@code exchange()} in each thread
98  * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
99  * those subsequent to a return from the corresponding {@code exchange()}
100  * in the other thread.
101  *
102  * @since 1.5
103  * @author Doug Lea and Bill Scherer and Michael Scott
104  * @param <V> The type of objects that may be exchanged
105  */
106 public class Exchanger<V> {
107 
108     /*
109      * Overview: The core algorithm is, for an exchange "slot",
110      * and a participant (caller) with an item:
111      *
112      * for (;;) {
113      *   if (slot is empty) {                       // offer
114      *     place item in a Node;
115      *     if (can CAS slot from empty to node) {
116      *       wait for release;
117      *       return matching item in node;
118      *     }
119      *   }
120      *   else if (can CAS slot from node to empty) { // release
121      *     get the item in node;
122      *     set matching item in node;
123      *     release waiting thread;
124      *   }
125      *   // else retry on CAS failure
126      * }
127      *
128      * This is among the simplest forms of a "dual data structure" --
129      * see Scott and Scherer's DISC 04 paper and
130      * http://www.cs.rochester.edu/research/synchronization/pseudocode/duals.html
131      *
132      * This works great in principle. But in practice, like many
133      * algorithms centered on atomic updates to a single location, it
134      * scales horribly when there are more than a few participants
135      * using the same Exchanger. So the implementation instead uses a
136      * form of elimination arena, that spreads out this contention by
137      * arranging that some threads typically use different slots,
138      * while still ensuring that eventually, any two parties will be
139      * able to exchange items. That is, we cannot completely partition
140      * across threads, but instead give threads arena indices that
141      * will on average grow under contention and shrink under lack of
142      * contention. We approach this by defining the Nodes that we need
143      * anyway as ThreadLocals, and include in them per-thread index
144      * and related bookkeeping state. (We can safely reuse per-thread
145      * nodes rather than creating them fresh each time because slots
146      * alternate between pointing to a node vs null, so cannot
147      * encounter ABA problems. However, we do need some care in
148      * resetting them between uses.)
149      *
150      * Implementing an effective arena requires allocating a bunch of
151      * space, so we only do so upon detecting contention (except on
152      * uniprocessors, where they wouldn't help, so aren't used).
153      * Otherwise, exchanges use the single-slot slotExchange method.
154      * On contention, not only must the slots be in different
155      * locations, but the locations must not encounter memory
156      * contention due to being on the same cache line (or more
157      * generally, the same coherence unit).  Because, as of this
158      * writing, there is no way to determine cacheline size, we define
159      * a value that is enough for common platforms.  Additionally,
160      * extra care elsewhere is taken to avoid other false/unintended
161      * sharing and to enhance locality, including adding padding (via
162      * @Contended) to Nodes, embedding "bound" as an Exchanger field.
163      *
164      * The arena starts out with only one used slot. We expand the
165      * effective arena size by tracking collisions; i.e., failed CASes
166      * while trying to exchange. By nature of the above algorithm, the
167      * only kinds of collision that reliably indicate contention are
168      * when two attempted releases collide -- one of two attempted
169      * offers can legitimately fail to CAS without indicating
170      * contention by more than one other thread. (Note: it is possible
171      * but not worthwhile to more precisely detect contention by
172      * reading slot values after CAS failures.)  When a thread has
173      * collided at each slot within the current arena bound, it tries
174      * to expand the arena size by one. We track collisions within
175      * bounds by using a version (sequence) number on the "bound"
176      * field, and conservatively reset collision counts when a
177      * participant notices that bound has been updated (in either
178      * direction).
179      *
180      * The effective arena size is reduced (when there is more than
181      * one slot) by giving up on waiting after a while and trying to
182      * decrement the arena size on expiration. The value of "a while"
183      * is an empirical matter.  We implement by piggybacking on the
184      * use of spin->yield->block that is essential for reasonable
185      * waiting performance anyway -- in a busy exchanger, offers are
186      * usually almost immediately released, in which case context
187      * switching on multiprocessors is extremely slow/wasteful.  Arena
188      * waits just omit the blocking part, and instead cancel. The spin
189      * count is empirically chosen to be a value that avoids blocking
190      * 99% of the time under maximum sustained exchange rates on a
191      * range of test machines. Spins and yields entail some limited
192      * randomness (using a cheap xorshift) to avoid regular patterns
193      * that can induce unproductive grow/shrink cycles. (Using a
194      * pseudorandom also helps regularize spin cycle duration by
195      * making branches unpredictable.)  Also, during an offer, a
196      * waiter can "know" that it will be released when its slot has
197      * changed, but cannot yet proceed until match is set.  In the
198      * mean time it cannot cancel the offer, so instead spins/yields.
199      * Note: It is possible to avoid this secondary check by changing
200      * the linearization point to be a CAS of the match field (as done
201      * in one case in the Scott & Scherer DISC paper), which also
202      * increases asynchrony a bit, at the expense of poorer collision
203      * detection and inability to always reuse per-thread nodes. So
204      * the current scheme is typically a better tradeoff.
205      *
206      * On collisions, indices traverse the arena cyclically in reverse
207      * order, restarting at the maximum index (which will tend to be
208      * sparsest) when bounds change. (On expirations, indices instead
209      * are halved until reaching 0.) It is possible (and has been
210      * tried) to use randomized, prime-value-stepped, or double-hash
211      * style traversal instead of simple cyclic traversal to reduce
212      * bunching.  But empirically, whatever benefits these may have
213      * don't overcome their added overhead: We are managing operations
214      * that occur very quickly unless there is sustained contention,
215      * so simpler/faster control policies work better than more
216      * accurate but slower ones.
217      *
218      * Because we use expiration for arena size control, we cannot
219      * throw TimeoutExceptions in the timed version of the public
220      * exchange method until the arena size has shrunken to zero (or
221      * the arena isn't enabled). This may delay response to timeout
222      * but is still within spec.
223      *
224      * Essentially all of the implementation is in methods
225      * slotExchange and arenaExchange. These have similar overall
226      * structure, but differ in too many details to combine. The
227      * slotExchange method uses the single Exchanger field "slot"
228      * rather than arena array elements. However, it still needs
229      * minimal collision detection to trigger arena construction.
230      * (The messiest part is making sure interrupt status and
231      * InterruptedExceptions come out right during transitions when
232      * both methods may be called. This is done by using null return
233      * as a sentinel to recheck interrupt status.)
234      *
235      * As is too common in this sort of code, methods are monolithic
236      * because most of the logic relies on reads of fields that are
237      * maintained as local variables so can't be nicely factored --
238      * mainly, here, bulky spin->yield->block/cancel code.  Note that
239      * field Node.item is not declared as volatile even though it is
240      * read by releasing threads, because they only do so after CAS
241      * operations that must precede access, and all uses by the owning
242      * thread are otherwise acceptably ordered by other operations.
243      * (Because the actual points of atomicity are slot CASes, it
244      * would also be legal for the write to Node.match in a release to
245      * be weaker than a full volatile write. However, this is not done
246      * because it could allow further postponement of the write,
247      * delaying progress.)
248      */
249 
250     /**
251      * The index distance (as a shift value) between any two used slots
252      * in the arena, spacing them out to avoid false sharing.
253      */
254     private static final int ASHIFT = 5;
255 
256     /**
257      * The maximum supported arena index. The maximum allocatable
258      * arena size is MMASK + 1. Must be a power of two minus one, less
259      * than (1<<(31-ASHIFT)). The cap of 255 (0xff) more than suffices
260      * for the expected scaling limits of the main algorithms.
261      */
262     private static final int MMASK = 0xff;
263 
264     /**
265      * Unit for sequence/version bits of bound field. Each successful
266      * change to the bound also adds SEQ.
267      */
268     private static final int SEQ = MMASK + 1;
269 
270     /** The number of CPUs, for sizing and spin control */
271     private static final int NCPU = Runtime.getRuntime().availableProcessors();
272 
273     /**
274      * The maximum slot index of the arena: The number of slots that
275      * can in principle hold all threads without contention, or at
276      * most the maximum indexable value.
277      */
278     static final int FULL = (NCPU >= (MMASK << 1)) ? MMASK : NCPU >>> 1;
279 
280     /**
281      * The bound for spins while waiting for a match. The actual
282      * number of iterations will on average be about twice this value
283      * due to randomization. Note: Spinning is disabled when NCPU==1.
284      */
285     private static final int SPINS = 1 << 10;
286 
287     /**
288      * Value representing null arguments/returns from public
289      * methods. Needed because the API originally didn't disallow null
290      * arguments, which it should have.
291      */
292     private static final Object NULL_ITEM = new Object();
293 
294     /**
295      * Sentinel value returned by internal exchange methods upon
296      * timeout, to avoid need for separate timed versions of these
297      * methods.
298      */
299     private static final Object TIMED_OUT = new Object();
300 
301     /**
302      * Nodes hold partially exchanged data, plus other per-thread
303      * bookkeeping. Padded via @Contended to reduce memory contention.
304      */
305     @jdk.internal.vm.annotation.Contended
306     static final class Node {
307         int index;              // Arena index
308         int bound;              // Last recorded value of Exchanger.bound
309         int collides;           // Number of CAS failures at current bound
310         int hash;               // Pseudo-random for spins
311         Object item;            // This thread's current item
312         volatile Object match;  // Item provided by releasing thread
313         volatile Thread parked; // Set to this thread when parked, else null
314     }
315 
316     /** The corresponding thread local class */
317     static final class Participant extends ThreadLocal<Node> {
initialValue()318         public Node initialValue() { return new Node(); }
319     }
320 
321     /**
322      * Per-thread state.
323      */
324     private final Participant participant;
325 
326     /**
327      * Elimination array; null until enabled (within slotExchange).
328      * Element accesses use emulation of volatile gets and CAS.
329      */
330     private volatile Node[] arena;
331 
332     /**
333      * Slot used until contention detected.
334      */
335     private volatile Node slot;
336 
337     /**
338      * The index of the largest valid arena position, OR'ed with SEQ
339      * number in high bits, incremented on each update.  The initial
340      * update from 0 to SEQ is used to ensure that the arena array is
341      * constructed only once.
342      */
343     private volatile int bound;
344 
345     /**
346      * Exchange function when arenas enabled. See above for explanation.
347      *
348      * @param item the (non-null) item to exchange
349      * @param timed true if the wait is timed
350      * @param ns if timed, the maximum wait time, else 0L
351      * @return the other thread's item; or null if interrupted; or
352      * TIMED_OUT if timed and timed out
353      */
arenaExchange(Object item, boolean timed, long ns)354     private final Object arenaExchange(Object item, boolean timed, long ns) {
355         Node[] a = arena;
356         int alen = a.length;
357         Node p = participant.get();
358         for (int i = p.index;;) {                      // access slot at i
359             int b, m, c;
360             int j = (i << ASHIFT) + ((1 << ASHIFT) - 1);
361             if (j < 0 || j >= alen)
362                 j = alen - 1;
363             Node q = (Node)AA.getAcquire(a, j);
364             if (q != null && AA.compareAndSet(a, j, q, null)) {
365                 Object v = q.item;                     // release
366                 q.match = item;
367                 Thread w = q.parked;
368                 if (w != null)
369                     LockSupport.unpark(w);
370                 return v;
371             }
372             else if (i <= (m = (b = bound) & MMASK) && q == null) {
373                 p.item = item;                         // offer
374                 if (AA.compareAndSet(a, j, null, p)) {
375                     long end = (timed && m == 0) ? System.nanoTime() + ns : 0L;
376                     Thread t = Thread.currentThread(); // wait
377                     for (int h = p.hash, spins = SPINS;;) {
378                         Object v = p.match;
379                         if (v != null) {
380                             MATCH.setRelease(p, null);
381                             p.item = null;             // clear for next use
382                             p.hash = h;
383                             return v;
384                         }
385                         else if (spins > 0) {
386                             h ^= h << 1; h ^= h >>> 3; h ^= h << 10; // xorshift
387                             if (h == 0)                // initialize hash
388                                 h = SPINS | (int)t.getId();
389                             else if (h < 0 &&          // approx 50% true
390                                      (--spins & ((SPINS >>> 1) - 1)) == 0)
391                                 Thread.yield();        // two yields per wait
392                         }
393                         else if (AA.getAcquire(a, j) != p)
394                             spins = SPINS;       // releaser hasn't set match yet
395                         else if (!t.isInterrupted() && m == 0 &&
396                                  (!timed ||
397                                   (ns = end - System.nanoTime()) > 0L)) {
398                             p.parked = t;              // minimize window
399                             if (AA.getAcquire(a, j) == p) {
400                                 if (ns == 0L)
401                                     LockSupport.park(this);
402                                 else
403                                     LockSupport.parkNanos(this, ns);
404                             }
405                             p.parked = null;
406                         }
407                         else if (AA.getAcquire(a, j) == p &&
408                                  AA.compareAndSet(a, j, p, null)) {
409                             if (m != 0)                // try to shrink
410                                 BOUND.compareAndSet(this, b, b + SEQ - 1);
411                             p.item = null;
412                             p.hash = h;
413                             i = p.index >>>= 1;        // descend
414                             if (Thread.interrupted())
415                                 return null;
416                             if (timed && m == 0 && ns <= 0L)
417                                 return TIMED_OUT;
418                             break;                     // expired; restart
419                         }
420                     }
421                 }
422                 else
423                     p.item = null;                     // clear offer
424             }
425             else {
426                 if (p.bound != b) {                    // stale; reset
427                     p.bound = b;
428                     p.collides = 0;
429                     i = (i != m || m == 0) ? m : m - 1;
430                 }
431                 else if ((c = p.collides) < m || m == FULL ||
432                          !BOUND.compareAndSet(this, b, b + SEQ + 1)) {
433                     p.collides = c + 1;
434                     i = (i == 0) ? m : i - 1;          // cyclically traverse
435                 }
436                 else
437                     i = m + 1;                         // grow
438                 p.index = i;
439             }
440         }
441     }
442 
443     /**
444      * Exchange function used until arenas enabled. See above for explanation.
445      *
446      * @param item the item to exchange
447      * @param timed true if the wait is timed
448      * @param ns if timed, the maximum wait time, else 0L
449      * @return the other thread's item; or null if either the arena
450      * was enabled or the thread was interrupted before completion; or
451      * TIMED_OUT if timed and timed out
452      */
slotExchange(Object item, boolean timed, long ns)453     private final Object slotExchange(Object item, boolean timed, long ns) {
454         Node p = participant.get();
455         Thread t = Thread.currentThread();
456         if (t.isInterrupted()) // preserve interrupt status so caller can recheck
457             return null;
458 
459         for (Node q;;) {
460             if ((q = slot) != null) {
461                 if (SLOT.compareAndSet(this, q, null)) {
462                     Object v = q.item;
463                     q.match = item;
464                     Thread w = q.parked;
465                     if (w != null)
466                         LockSupport.unpark(w);
467                     return v;
468                 }
469                 // create arena on contention, but continue until slot null
470                 if (NCPU > 1 && bound == 0 &&
471                     BOUND.compareAndSet(this, 0, SEQ))
472                     arena = new Node[(FULL + 2) << ASHIFT];
473             }
474             else if (arena != null)
475                 return null; // caller must reroute to arenaExchange
476             else {
477                 p.item = item;
478                 if (SLOT.compareAndSet(this, null, p))
479                     break;
480                 p.item = null;
481             }
482         }
483 
484         // await release
485         int h = p.hash;
486         long end = timed ? System.nanoTime() + ns : 0L;
487         int spins = (NCPU > 1) ? SPINS : 1;
488         Object v;
489         while ((v = p.match) == null) {
490             if (spins > 0) {
491                 h ^= h << 1; h ^= h >>> 3; h ^= h << 10;
492                 if (h == 0)
493                     h = SPINS | (int)t.getId();
494                 else if (h < 0 && (--spins & ((SPINS >>> 1) - 1)) == 0)
495                     Thread.yield();
496             }
497             else if (slot != p)
498                 spins = SPINS;
499             else if (!t.isInterrupted() && arena == null &&
500                      (!timed || (ns = end - System.nanoTime()) > 0L)) {
501                 p.parked = t;
502                 if (slot == p) {
503                     if (ns == 0L)
504                         LockSupport.park(this);
505                     else
506                         LockSupport.parkNanos(this, ns);
507                 }
508                 p.parked = null;
509             }
510             else if (SLOT.compareAndSet(this, p, null)) {
511                 v = timed && ns <= 0L && !t.isInterrupted() ? TIMED_OUT : null;
512                 break;
513             }
514         }
515         MATCH.setRelease(p, null);
516         p.item = null;
517         p.hash = h;
518         return v;
519     }
520 
521     /**
522      * Creates a new Exchanger.
523      */
Exchanger()524     public Exchanger() {
525         participant = new Participant();
526     }
527 
528     /**
529      * Waits for another thread to arrive at this exchange point (unless
530      * the current thread is {@linkplain Thread#interrupt interrupted}),
531      * and then transfers the given object to it, receiving its object
532      * in return.
533      *
534      * <p>If another thread is already waiting at the exchange point then
535      * it is resumed for thread scheduling purposes and receives the object
536      * passed in by the current thread.  The current thread returns immediately,
537      * receiving the object passed to the exchange by that other thread.
538      *
539      * <p>If no other thread is already waiting at the exchange then the
540      * current thread is disabled for thread scheduling purposes and lies
541      * dormant until one of two things happens:
542      * <ul>
543      * <li>Some other thread enters the exchange; or
544      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
545      * the current thread.
546      * </ul>
547      * <p>If the current thread:
548      * <ul>
549      * <li>has its interrupted status set on entry to this method; or
550      * <li>is {@linkplain Thread#interrupt interrupted} while waiting
551      * for the exchange,
552      * </ul>
553      * then {@link InterruptedException} is thrown and the current thread's
554      * interrupted status is cleared.
555      *
556      * @param x the object to exchange
557      * @return the object provided by the other thread
558      * @throws InterruptedException if the current thread was
559      *         interrupted while waiting
560      */
561     @SuppressWarnings("unchecked")
exchange(V x)562     public V exchange(V x) throws InterruptedException {
563         Object v;
564         Node[] a;
565         Object item = (x == null) ? NULL_ITEM : x; // translate null args
566         if (((a = arena) != null ||
567              (v = slotExchange(item, false, 0L)) == null) &&
568             (Thread.interrupted() || // disambiguates null return
569              (v = arenaExchange(item, false, 0L)) == null))
570             throw new InterruptedException();
571         return (v == NULL_ITEM) ? null : (V)v;
572     }
573 
574     /**
575      * Waits for another thread to arrive at this exchange point (unless
576      * the current thread is {@linkplain Thread#interrupt interrupted} or
577      * the specified waiting time elapses), and then transfers the given
578      * object to it, receiving its object in return.
579      *
580      * <p>If another thread is already waiting at the exchange point then
581      * it is resumed for thread scheduling purposes and receives the object
582      * passed in by the current thread.  The current thread returns immediately,
583      * receiving the object passed to the exchange by that other thread.
584      *
585      * <p>If no other thread is already waiting at the exchange then the
586      * current thread is disabled for thread scheduling purposes and lies
587      * dormant until one of three things happens:
588      * <ul>
589      * <li>Some other thread enters the exchange; or
590      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
591      * the current thread; or
592      * <li>The specified waiting time elapses.
593      * </ul>
594      * <p>If the current thread:
595      * <ul>
596      * <li>has its interrupted status set on entry to this method; or
597      * <li>is {@linkplain Thread#interrupt interrupted} while waiting
598      * for the exchange,
599      * </ul>
600      * then {@link InterruptedException} is thrown and the current thread's
601      * interrupted status is cleared.
602      *
603      * <p>If the specified waiting time elapses then {@link
604      * TimeoutException} is thrown.  If the time is less than or equal
605      * to zero, the method will not wait at all.
606      *
607      * @param x the object to exchange
608      * @param timeout the maximum time to wait
609      * @param unit the time unit of the {@code timeout} argument
610      * @return the object provided by the other thread
611      * @throws InterruptedException if the current thread was
612      *         interrupted while waiting
613      * @throws TimeoutException if the specified waiting time elapses
614      *         before another thread enters the exchange
615      */
616     @SuppressWarnings("unchecked")
exchange(V x, long timeout, TimeUnit unit)617     public V exchange(V x, long timeout, TimeUnit unit)
618         throws InterruptedException, TimeoutException {
619         Object v;
620         Object item = (x == null) ? NULL_ITEM : x;
621         long ns = unit.toNanos(timeout);
622         if ((arena != null ||
623              (v = slotExchange(item, true, ns)) == null) &&
624             (Thread.interrupted() ||
625              (v = arenaExchange(item, true, ns)) == null))
626             throw new InterruptedException();
627         if (v == TIMED_OUT)
628             throw new TimeoutException();
629         return (v == NULL_ITEM) ? null : (V)v;
630     }
631 
632     // VarHandle mechanics
633     private static final VarHandle BOUND;
634     private static final VarHandle SLOT;
635     private static final VarHandle MATCH;
636     private static final VarHandle AA;
637     static {
638         try {
639             MethodHandles.Lookup l = MethodHandles.lookup();
640             BOUND = l.findVarHandle(Exchanger.class, "bound", int.class);
641             SLOT = l.findVarHandle(Exchanger.class, "slot", Node.class);
642             MATCH = l.findVarHandle(Node.class, "match", Object.class);
643             AA = MethodHandles.arrayElementVarHandle(Node[].class);
644         } catch (ReflectiveOperationException e) {
645             throw new ExceptionInInitializerError(e);
646         }
647     }
648 
649 }
650