rt/emul/compact/src/main/java/java/util/concurrent/locks/LockSupport.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Sat, 19 Mar 2016 10:46:31 +0100
branchjdk7-b147
changeset 1890 212417b74b72
child 1894 75ee4eca04e3
permissions -rw-r--r--
Bringing in all concurrent package from JDK7-b147
     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 with assistance from members of JCP JSR-166
    32  * Expert Group and released to the public domain, as explained at
    33  * http://creativecommons.org/publicdomain/zero/1.0/
    34  */
    35 
    36 package java.util.concurrent.locks;
    37 import java.util.concurrent.*;
    38 import sun.misc.Unsafe;
    39 
    40 
    41 /**
    42  * Basic thread blocking primitives for creating locks and other
    43  * synchronization classes.
    44  *
    45  * <p>This class associates, with each thread that uses it, a permit
    46  * (in the sense of the {@link java.util.concurrent.Semaphore
    47  * Semaphore} class). A call to {@code park} will return immediately
    48  * if the permit is available, consuming it in the process; otherwise
    49  * it <em>may</em> block.  A call to {@code unpark} makes the permit
    50  * available, if it was not already available. (Unlike with Semaphores
    51  * though, permits do not accumulate. There is at most one.)
    52  *
    53  * <p>Methods {@code park} and {@code unpark} provide efficient
    54  * means of blocking and unblocking threads that do not encounter the
    55  * problems that cause the deprecated methods {@code Thread.suspend}
    56  * and {@code Thread.resume} to be unusable for such purposes: Races
    57  * between one thread invoking {@code park} and another thread trying
    58  * to {@code unpark} it will preserve liveness, due to the
    59  * permit. Additionally, {@code park} will return if the caller's
    60  * thread was interrupted, and timeout versions are supported. The
    61  * {@code park} method may also return at any other time, for "no
    62  * reason", so in general must be invoked within a loop that rechecks
    63  * conditions upon return. In this sense {@code park} serves as an
    64  * optimization of a "busy wait" that does not waste as much time
    65  * spinning, but must be paired with an {@code unpark} to be
    66  * effective.
    67  *
    68  * <p>The three forms of {@code park} each also support a
    69  * {@code blocker} object parameter. This object is recorded while
    70  * the thread is blocked to permit monitoring and diagnostic tools to
    71  * identify the reasons that threads are blocked. (Such tools may
    72  * access blockers using method {@link #getBlocker}.) The use of these
    73  * forms rather than the original forms without this parameter is
    74  * strongly encouraged. The normal argument to supply as a
    75  * {@code blocker} within a lock implementation is {@code this}.
    76  *
    77  * <p>These methods are designed to be used as tools for creating
    78  * higher-level synchronization utilities, and are not in themselves
    79  * useful for most concurrency control applications.  The {@code park}
    80  * method is designed for use only in constructions of the form:
    81  * <pre>while (!canProceed()) { ... LockSupport.park(this); }</pre>
    82  * where neither {@code canProceed} nor any other actions prior to the
    83  * call to {@code park} entail locking or blocking.  Because only one
    84  * permit is associated with each thread, any intermediary uses of
    85  * {@code park} could interfere with its intended effects.
    86  *
    87  * <p><b>Sample Usage.</b> Here is a sketch of a first-in-first-out
    88  * non-reentrant lock class:
    89  * <pre>{@code
    90  * class FIFOMutex {
    91  *   private final AtomicBoolean locked = new AtomicBoolean(false);
    92  *   private final Queue<Thread> waiters
    93  *     = new ConcurrentLinkedQueue<Thread>();
    94  *
    95  *   public void lock() {
    96  *     boolean wasInterrupted = false;
    97  *     Thread current = Thread.currentThread();
    98  *     waiters.add(current);
    99  *
   100  *     // Block while not first in queue or cannot acquire lock
   101  *     while (waiters.peek() != current ||
   102  *            !locked.compareAndSet(false, true)) {
   103  *        LockSupport.park(this);
   104  *        if (Thread.interrupted()) // ignore interrupts while waiting
   105  *          wasInterrupted = true;
   106  *     }
   107  *
   108  *     waiters.remove();
   109  *     if (wasInterrupted)          // reassert interrupt status on exit
   110  *        current.interrupt();
   111  *   }
   112  *
   113  *   public void unlock() {
   114  *     locked.set(false);
   115  *     LockSupport.unpark(waiters.peek());
   116  *   }
   117  * }}</pre>
   118  */
   119 
   120 public class LockSupport {
   121     private LockSupport() {} // Cannot be instantiated.
   122 
   123     // Hotspot implementation via intrinsics API
   124     private static final Unsafe unsafe = Unsafe.getUnsafe();
   125     private static final long parkBlockerOffset;
   126 
   127     static {
   128         try {
   129             parkBlockerOffset = unsafe.objectFieldOffset
   130                 (java.lang.Thread.class.getDeclaredField("parkBlocker"));
   131         } catch (Exception ex) { throw new Error(ex); }
   132     }
   133 
   134     private static void setBlocker(Thread t, Object arg) {
   135         // Even though volatile, hotspot doesn't need a write barrier here.
   136         unsafe.putObject(t, parkBlockerOffset, arg);
   137     }
   138 
   139     /**
   140      * Makes available the permit for the given thread, if it
   141      * was not already available.  If the thread was blocked on
   142      * {@code park} then it will unblock.  Otherwise, its next call
   143      * to {@code park} is guaranteed not to block. This operation
   144      * is not guaranteed to have any effect at all if the given
   145      * thread has not been started.
   146      *
   147      * @param thread the thread to unpark, or {@code null}, in which case
   148      *        this operation has no effect
   149      */
   150     public static void unpark(Thread thread) {
   151         if (thread != null)
   152             unsafe.unpark(thread);
   153     }
   154 
   155     /**
   156      * Disables the current thread for thread scheduling purposes unless the
   157      * permit is available.
   158      *
   159      * <p>If the permit is available then it is consumed and the call returns
   160      * immediately; otherwise
   161      * the current thread becomes disabled for thread scheduling
   162      * purposes and lies dormant until one of three things happens:
   163      *
   164      * <ul>
   165      * <li>Some other thread invokes {@link #unpark unpark} with the
   166      * current thread as the target; or
   167      *
   168      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   169      * the current thread; or
   170      *
   171      * <li>The call spuriously (that is, for no reason) returns.
   172      * </ul>
   173      *
   174      * <p>This method does <em>not</em> report which of these caused the
   175      * method to return. Callers should re-check the conditions which caused
   176      * the thread to park in the first place. Callers may also determine,
   177      * for example, the interrupt status of the thread upon return.
   178      *
   179      * @param blocker the synchronization object responsible for this
   180      *        thread parking
   181      * @since 1.6
   182      */
   183     public static void park(Object blocker) {
   184         Thread t = Thread.currentThread();
   185         setBlocker(t, blocker);
   186         unsafe.park(false, 0L);
   187         setBlocker(t, null);
   188     }
   189 
   190     /**
   191      * Disables the current thread for thread scheduling purposes, for up to
   192      * the specified waiting time, unless the permit is available.
   193      *
   194      * <p>If the permit is available then it is consumed and the call
   195      * returns immediately; otherwise the current thread becomes disabled
   196      * for thread scheduling purposes and lies dormant until one of four
   197      * things happens:
   198      *
   199      * <ul>
   200      * <li>Some other thread invokes {@link #unpark unpark} with the
   201      * current thread as the target; or
   202      *
   203      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   204      * the current thread; or
   205      *
   206      * <li>The specified waiting time elapses; or
   207      *
   208      * <li>The call spuriously (that is, for no reason) returns.
   209      * </ul>
   210      *
   211      * <p>This method does <em>not</em> report which of these caused the
   212      * method to return. Callers should re-check the conditions which caused
   213      * the thread to park in the first place. Callers may also determine,
   214      * for example, the interrupt status of the thread, or the elapsed time
   215      * upon return.
   216      *
   217      * @param blocker the synchronization object responsible for this
   218      *        thread parking
   219      * @param nanos the maximum number of nanoseconds to wait
   220      * @since 1.6
   221      */
   222     public static void parkNanos(Object blocker, long nanos) {
   223         if (nanos > 0) {
   224             Thread t = Thread.currentThread();
   225             setBlocker(t, blocker);
   226             unsafe.park(false, nanos);
   227             setBlocker(t, null);
   228         }
   229     }
   230 
   231     /**
   232      * Disables the current thread for thread scheduling purposes, until
   233      * the specified deadline, unless the permit is available.
   234      *
   235      * <p>If the permit is available then it is consumed and the call
   236      * returns immediately; otherwise the current thread becomes disabled
   237      * for thread scheduling purposes and lies dormant until one of four
   238      * things happens:
   239      *
   240      * <ul>
   241      * <li>Some other thread invokes {@link #unpark unpark} with the
   242      * current thread as the target; or
   243      *
   244      * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
   245      * current thread; or
   246      *
   247      * <li>The specified deadline passes; or
   248      *
   249      * <li>The call spuriously (that is, for no reason) returns.
   250      * </ul>
   251      *
   252      * <p>This method does <em>not</em> report which of these caused the
   253      * method to return. Callers should re-check the conditions which caused
   254      * the thread to park in the first place. Callers may also determine,
   255      * for example, the interrupt status of the thread, or the current time
   256      * upon return.
   257      *
   258      * @param blocker the synchronization object responsible for this
   259      *        thread parking
   260      * @param deadline the absolute time, in milliseconds from the Epoch,
   261      *        to wait until
   262      * @since 1.6
   263      */
   264     public static void parkUntil(Object blocker, long deadline) {
   265         Thread t = Thread.currentThread();
   266         setBlocker(t, blocker);
   267         unsafe.park(true, deadline);
   268         setBlocker(t, null);
   269     }
   270 
   271     /**
   272      * Returns the blocker object supplied to the most recent
   273      * invocation of a park method that has not yet unblocked, or null
   274      * if not blocked.  The value returned is just a momentary
   275      * snapshot -- the thread may have since unblocked or blocked on a
   276      * different blocker object.
   277      *
   278      * @param t the thread
   279      * @return the blocker
   280      * @throws NullPointerException if argument is null
   281      * @since 1.6
   282      */
   283     public static Object getBlocker(Thread t) {
   284         if (t == null)
   285             throw new NullPointerException();
   286         return unsafe.getObjectVolatile(t, parkBlockerOffset);
   287     }
   288 
   289     /**
   290      * Disables the current thread for thread scheduling purposes unless the
   291      * permit is available.
   292      *
   293      * <p>If the permit is available then it is consumed and the call
   294      * returns immediately; otherwise the current thread becomes disabled
   295      * for thread scheduling purposes and lies dormant until one of three
   296      * things happens:
   297      *
   298      * <ul>
   299      *
   300      * <li>Some other thread invokes {@link #unpark unpark} with the
   301      * current thread as the target; or
   302      *
   303      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   304      * the current thread; or
   305      *
   306      * <li>The call spuriously (that is, for no reason) returns.
   307      * </ul>
   308      *
   309      * <p>This method does <em>not</em> report which of these caused the
   310      * method to return. Callers should re-check the conditions which caused
   311      * the thread to park in the first place. Callers may also determine,
   312      * for example, the interrupt status of the thread upon return.
   313      */
   314     public static void park() {
   315         unsafe.park(false, 0L);
   316     }
   317 
   318     /**
   319      * Disables the current thread for thread scheduling purposes, for up to
   320      * the specified waiting time, unless the permit is available.
   321      *
   322      * <p>If the permit is available then it is consumed and the call
   323      * returns immediately; otherwise the current thread becomes disabled
   324      * for thread scheduling purposes and lies dormant until one of four
   325      * things happens:
   326      *
   327      * <ul>
   328      * <li>Some other thread invokes {@link #unpark unpark} with the
   329      * current thread as the target; or
   330      *
   331      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   332      * the current thread; or
   333      *
   334      * <li>The specified waiting time elapses; or
   335      *
   336      * <li>The call spuriously (that is, for no reason) returns.
   337      * </ul>
   338      *
   339      * <p>This method does <em>not</em> report which of these caused the
   340      * method to return. Callers should re-check the conditions which caused
   341      * the thread to park in the first place. Callers may also determine,
   342      * for example, the interrupt status of the thread, or the elapsed time
   343      * upon return.
   344      *
   345      * @param nanos the maximum number of nanoseconds to wait
   346      */
   347     public static void parkNanos(long nanos) {
   348         if (nanos > 0)
   349             unsafe.park(false, nanos);
   350     }
   351 
   352     /**
   353      * Disables the current thread for thread scheduling purposes, until
   354      * the specified deadline, unless the permit is available.
   355      *
   356      * <p>If the permit is available then it is consumed and the call
   357      * returns immediately; otherwise the current thread becomes disabled
   358      * for thread scheduling purposes and lies dormant until one of four
   359      * things happens:
   360      *
   361      * <ul>
   362      * <li>Some other thread invokes {@link #unpark unpark} with the
   363      * current thread as the target; or
   364      *
   365      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
   366      * the current thread; or
   367      *
   368      * <li>The specified deadline passes; or
   369      *
   370      * <li>The call spuriously (that is, for no reason) returns.
   371      * </ul>
   372      *
   373      * <p>This method does <em>not</em> report which of these caused the
   374      * method to return. Callers should re-check the conditions which caused
   375      * the thread to park in the first place. Callers may also determine,
   376      * for example, the interrupt status of the thread, or the current time
   377      * upon return.
   378      *
   379      * @param deadline the absolute time, in milliseconds from the Epoch,
   380      *        to wait until
   381      */
   382     public static void parkUntil(long deadline) {
   383         unsafe.park(true, deadline);
   384     }
   385 }