Save This Page
Home » openjdk-7 » java » util » concurrent » locks » [javadoc | source]
    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   }

Save This Page
Home » openjdk-7 » java » util » concurrent » locks » [javadoc | source]