< prev index next >

src/java.base/share/classes/java/util/concurrent/Exchanger.java

Print this page
8211283: Miscellaneous changes imported from jsr166 CVS 2018-11
Reviewed-by: martin, chegar


 547      * <ul>
 548      * <li>has its interrupted status set on entry to this method; or
 549      * <li>is {@linkplain Thread#interrupt interrupted} while waiting
 550      * for the exchange,
 551      * </ul>
 552      * then {@link InterruptedException} is thrown and the current thread's
 553      * interrupted status is cleared.
 554      *
 555      * @param x the object to exchange
 556      * @return the object provided by the other thread
 557      * @throws InterruptedException if the current thread was
 558      *         interrupted while waiting
 559      */
 560     @SuppressWarnings("unchecked")
 561     public V exchange(V x) throws InterruptedException {
 562         Object v;
 563         Node[] a;
 564         Object item = (x == null) ? NULL_ITEM : x; // translate null args
 565         if (((a = arena) != null ||
 566              (v = slotExchange(item, false, 0L)) == null) &&
 567             ((Thread.interrupted() || // disambiguates null return
 568               (v = arenaExchange(item, false, 0L)) == null)))
 569             throw new InterruptedException();
 570         return (v == NULL_ITEM) ? null : (V)v;
 571     }
 572 
 573     /**
 574      * Waits for another thread to arrive at this exchange point (unless
 575      * the current thread is {@linkplain Thread#interrupt interrupted} or
 576      * the specified waiting time elapses), and then transfers the given
 577      * object to it, receiving its object in return.
 578      *
 579      * <p>If another thread is already waiting at the exchange point then
 580      * it is resumed for thread scheduling purposes and receives the object
 581      * passed in by the current thread.  The current thread returns immediately,
 582      * receiving the object passed to the exchange by that other thread.
 583      *
 584      * <p>If no other thread is already waiting at the exchange then the
 585      * current thread is disabled for thread scheduling purposes and lies
 586      * dormant until one of three things happens:
 587      * <ul>
 588      * <li>Some other thread enters the exchange; or


 603      * TimeoutException} is thrown.  If the time is less than or equal
 604      * to zero, the method will not wait at all.
 605      *
 606      * @param x the object to exchange
 607      * @param timeout the maximum time to wait
 608      * @param unit the time unit of the {@code timeout} argument
 609      * @return the object provided by the other thread
 610      * @throws InterruptedException if the current thread was
 611      *         interrupted while waiting
 612      * @throws TimeoutException if the specified waiting time elapses
 613      *         before another thread enters the exchange
 614      */
 615     @SuppressWarnings("unchecked")
 616     public V exchange(V x, long timeout, TimeUnit unit)
 617         throws InterruptedException, TimeoutException {
 618         Object v;
 619         Object item = (x == null) ? NULL_ITEM : x;
 620         long ns = unit.toNanos(timeout);
 621         if ((arena != null ||
 622              (v = slotExchange(item, true, ns)) == null) &&
 623             ((Thread.interrupted() ||
 624               (v = arenaExchange(item, true, ns)) == null)))
 625             throw new InterruptedException();
 626         if (v == TIMED_OUT)
 627             throw new TimeoutException();
 628         return (v == NULL_ITEM) ? null : (V)v;
 629     }
 630 
 631     // VarHandle mechanics
 632     private static final VarHandle BOUND;
 633     private static final VarHandle SLOT;
 634     private static final VarHandle MATCH;
 635     private static final VarHandle AA;
 636     static {
 637         try {
 638             MethodHandles.Lookup l = MethodHandles.lookup();
 639             BOUND = l.findVarHandle(Exchanger.class, "bound", int.class);
 640             SLOT = l.findVarHandle(Exchanger.class, "slot", Node.class);
 641             MATCH = l.findVarHandle(Node.class, "match", Object.class);
 642             AA = MethodHandles.arrayElementVarHandle(Node[].class);
 643         } catch (ReflectiveOperationException e) {
 644             throw new ExceptionInInitializerError(e);


 547      * <ul>
 548      * <li>has its interrupted status set on entry to this method; or
 549      * <li>is {@linkplain Thread#interrupt interrupted} while waiting
 550      * for the exchange,
 551      * </ul>
 552      * then {@link InterruptedException} is thrown and the current thread's
 553      * interrupted status is cleared.
 554      *
 555      * @param x the object to exchange
 556      * @return the object provided by the other thread
 557      * @throws InterruptedException if the current thread was
 558      *         interrupted while waiting
 559      */
 560     @SuppressWarnings("unchecked")
 561     public V exchange(V x) throws InterruptedException {
 562         Object v;
 563         Node[] a;
 564         Object item = (x == null) ? NULL_ITEM : x; // translate null args
 565         if (((a = arena) != null ||
 566              (v = slotExchange(item, false, 0L)) == null) &&
 567             (Thread.interrupted() || // disambiguates null return
 568              (v = arenaExchange(item, false, 0L)) == null))
 569             throw new InterruptedException();
 570         return (v == NULL_ITEM) ? null : (V)v;
 571     }
 572 
 573     /**
 574      * Waits for another thread to arrive at this exchange point (unless
 575      * the current thread is {@linkplain Thread#interrupt interrupted} or
 576      * the specified waiting time elapses), and then transfers the given
 577      * object to it, receiving its object in return.
 578      *
 579      * <p>If another thread is already waiting at the exchange point then
 580      * it is resumed for thread scheduling purposes and receives the object
 581      * passed in by the current thread.  The current thread returns immediately,
 582      * receiving the object passed to the exchange by that other thread.
 583      *
 584      * <p>If no other thread is already waiting at the exchange then the
 585      * current thread is disabled for thread scheduling purposes and lies
 586      * dormant until one of three things happens:
 587      * <ul>
 588      * <li>Some other thread enters the exchange; or


 603      * TimeoutException} is thrown.  If the time is less than or equal
 604      * to zero, the method will not wait at all.
 605      *
 606      * @param x the object to exchange
 607      * @param timeout the maximum time to wait
 608      * @param unit the time unit of the {@code timeout} argument
 609      * @return the object provided by the other thread
 610      * @throws InterruptedException if the current thread was
 611      *         interrupted while waiting
 612      * @throws TimeoutException if the specified waiting time elapses
 613      *         before another thread enters the exchange
 614      */
 615     @SuppressWarnings("unchecked")
 616     public V exchange(V x, long timeout, TimeUnit unit)
 617         throws InterruptedException, TimeoutException {
 618         Object v;
 619         Object item = (x == null) ? NULL_ITEM : x;
 620         long ns = unit.toNanos(timeout);
 621         if ((arena != null ||
 622              (v = slotExchange(item, true, ns)) == null) &&
 623             (Thread.interrupted() ||
 624              (v = arenaExchange(item, true, ns)) == null))
 625             throw new InterruptedException();
 626         if (v == TIMED_OUT)
 627             throw new TimeoutException();
 628         return (v == NULL_ITEM) ? null : (V)v;
 629     }
 630 
 631     // VarHandle mechanics
 632     private static final VarHandle BOUND;
 633     private static final VarHandle SLOT;
 634     private static final VarHandle MATCH;
 635     private static final VarHandle AA;
 636     static {
 637         try {
 638             MethodHandles.Lookup l = MethodHandles.lookup();
 639             BOUND = l.findVarHandle(Exchanger.class, "bound", int.class);
 640             SLOT = l.findVarHandle(Exchanger.class, "slot", Node.class);
 641             MATCH = l.findVarHandle(Node.class, "match", Object.class);
 642             AA = MethodHandles.arrayElementVarHandle(Node[].class);
 643         } catch (ReflectiveOperationException e) {
 644             throw new ExceptionInInitializerError(e);
< prev index next >