Source for java.util.concurrent.locks.LockSupport

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