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