src/share/classes/java/util/concurrent/locks/LockSupport.java

Print this page




 103  *            !locked.compareAndSet(false, true)) {
 104  *        LockSupport.park(this);
 105  *        if (Thread.interrupted()) // ignore interrupts while waiting
 106  *          wasInterrupted = true;
 107  *     }
 108  *
 109  *     waiters.remove();
 110  *     if (wasInterrupted)          // reassert interrupt status on exit
 111  *        current.interrupt();
 112  *   }
 113  *
 114  *   public void unlock() {
 115  *     locked.set(false);
 116  *     LockSupport.unpark(waiters.peek());
 117  *   }
 118  * }}</pre>
 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 }


 103  *            !locked.compareAndSet(false, true)) {
 104  *       LockSupport.park(this);
 105  *       if (Thread.interrupted()) // ignore interrupts while waiting
 106  *         wasInterrupted = true;
 107  *     }
 108  *
 109  *     waiters.remove();
 110  *     if (wasInterrupted)          // reassert interrupt status on exit
 111  *       current.interrupt();
 112  *   }
 113  *
 114  *   public void unlock() {
 115  *     locked.set(false);
 116  *     LockSupport.unpark(waiters.peek());
 117  *   }
 118  * }}</pre>
 119  */
 120 public class LockSupport {
 121     private LockSupport() {} // Cannot be instantiated.
 122 











 123     private static void setBlocker(Thread t, Object arg) {
 124         // Even though volatile, hotspot doesn't need a write barrier here.
 125         UNSAFE.putObject(t, parkBlockerOffset, arg);
 126     }
 127 
 128     /**
 129      * Makes available the permit for the given thread, if it
 130      * was not already available.  If the thread was blocked on
 131      * {@code park} then it will unblock.  Otherwise, its next call
 132      * to {@code park} is guaranteed not to block. This operation
 133      * is not guaranteed to have any effect at all if the given
 134      * thread has not been started.
 135      *
 136      * @param thread the thread to unpark, or {@code null}, in which case
 137      *        this operation has no effect
 138      */
 139     public static void unpark(Thread thread) {
 140         if (thread != null)
 141             UNSAFE.unpark(thread);
 142     }
 143 
 144     /**
 145      * Disables the current thread for thread scheduling purposes unless the
 146      * permit is available.
 147      *
 148      * <p>If the permit is available then it is consumed and the call returns
 149      * immediately; otherwise
 150      * the current thread becomes disabled for thread scheduling
 151      * purposes and lies dormant until one of three things happens:
 152      *
 153      * <ul>
 154      * <li>Some other thread invokes {@link #unpark unpark} with the
 155      * current thread as the target; or
 156      *
 157      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
 158      * the current thread; or
 159      *
 160      * <li>The call spuriously (that is, for no reason) returns.
 161      * </ul>
 162      *
 163      * <p>This method does <em>not</em> report which of these caused the
 164      * method to return. Callers should re-check the conditions which caused
 165      * the thread to park in the first place. Callers may also determine,
 166      * for example, the interrupt status of the thread upon return.
 167      *
 168      * @param blocker the synchronization object responsible for this
 169      *        thread parking
 170      * @since 1.6
 171      */
 172     public static void park(Object blocker) {
 173         Thread t = Thread.currentThread();
 174         setBlocker(t, blocker);
 175         UNSAFE.park(false, 0L);
 176         setBlocker(t, null);
 177     }
 178 
 179     /**
 180      * Disables the current thread for thread scheduling purposes, for up to
 181      * the specified waiting time, unless the permit is available.
 182      *
 183      * <p>If the permit is available then it is consumed and the call
 184      * returns immediately; otherwise the current thread becomes disabled
 185      * for thread scheduling purposes and lies dormant until one of four
 186      * things happens:
 187      *
 188      * <ul>
 189      * <li>Some other thread invokes {@link #unpark unpark} with the
 190      * current thread as the target; or
 191      *
 192      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
 193      * the current thread; or
 194      *
 195      * <li>The specified waiting time elapses; or
 196      *
 197      * <li>The call spuriously (that is, for no reason) returns.
 198      * </ul>
 199      *
 200      * <p>This method does <em>not</em> report which of these caused the
 201      * method to return. Callers should re-check the conditions which caused
 202      * the thread to park in the first place. Callers may also determine,
 203      * for example, the interrupt status of the thread, or the elapsed time
 204      * upon return.
 205      *
 206      * @param blocker the synchronization object responsible for this
 207      *        thread parking
 208      * @param nanos the maximum number of nanoseconds to wait
 209      * @since 1.6
 210      */
 211     public static void parkNanos(Object blocker, long nanos) {
 212         if (nanos > 0) {
 213             Thread t = Thread.currentThread();
 214             setBlocker(t, blocker);
 215             UNSAFE.park(false, nanos);
 216             setBlocker(t, null);
 217         }
 218     }
 219 
 220     /**
 221      * Disables the current thread for thread scheduling purposes, until
 222      * the specified deadline, unless the permit is available.
 223      *
 224      * <p>If the permit is available then it is consumed and the call
 225      * returns immediately; otherwise the current thread becomes disabled
 226      * for thread scheduling purposes and lies dormant until one of four
 227      * things happens:
 228      *
 229      * <ul>
 230      * <li>Some other thread invokes {@link #unpark unpark} with the
 231      * current thread as the target; or
 232      *
 233      * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
 234      * current thread; or
 235      *
 236      * <li>The specified deadline passes; or
 237      *
 238      * <li>The call spuriously (that is, for no reason) returns.
 239      * </ul>
 240      *
 241      * <p>This method does <em>not</em> report which of these caused the
 242      * method to return. Callers should re-check the conditions which caused
 243      * the thread to park in the first place. Callers may also determine,
 244      * for example, the interrupt status of the thread, or the current time
 245      * upon return.
 246      *
 247      * @param blocker the synchronization object responsible for this
 248      *        thread parking
 249      * @param deadline the absolute time, in milliseconds from the Epoch,
 250      *        to wait until
 251      * @since 1.6
 252      */
 253     public static void parkUntil(Object blocker, long deadline) {
 254         Thread t = Thread.currentThread();
 255         setBlocker(t, blocker);
 256         UNSAFE.park(true, deadline);
 257         setBlocker(t, null);
 258     }
 259 
 260     /**
 261      * Returns the blocker object supplied to the most recent
 262      * invocation of a park method that has not yet unblocked, or null
 263      * if not blocked.  The value returned is just a momentary
 264      * snapshot -- the thread may have since unblocked or blocked on a
 265      * different blocker object.
 266      *
 267      * @param t the thread
 268      * @return the blocker
 269      * @throws NullPointerException if argument is null
 270      * @since 1.6
 271      */
 272     public static Object getBlocker(Thread t) {
 273         if (t == null)
 274             throw new NullPointerException();
 275         return UNSAFE.getObjectVolatile(t, parkBlockerOffset);
 276     }
 277 
 278     /**
 279      * Disables the current thread for thread scheduling purposes unless the
 280      * permit is available.
 281      *
 282      * <p>If the permit is available then it is consumed and the call
 283      * returns immediately; otherwise the current thread becomes disabled
 284      * for thread scheduling purposes and lies dormant until one of three
 285      * things happens:
 286      *
 287      * <ul>
 288      *
 289      * <li>Some other thread invokes {@link #unpark unpark} with the
 290      * current thread as the target; or
 291      *
 292      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
 293      * the current thread; or
 294      *
 295      * <li>The call spuriously (that is, for no reason) returns.
 296      * </ul>
 297      *
 298      * <p>This method does <em>not</em> report which of these caused the
 299      * method to return. Callers should re-check the conditions which caused
 300      * the thread to park in the first place. Callers may also determine,
 301      * for example, the interrupt status of the thread upon return.
 302      */
 303     public static void park() {
 304         UNSAFE.park(false, 0L);
 305     }
 306 
 307     /**
 308      * Disables the current thread for thread scheduling purposes, for up to
 309      * the specified waiting time, unless the permit is available.
 310      *
 311      * <p>If the permit is available then it is consumed and the call
 312      * returns immediately; otherwise the current thread becomes disabled
 313      * for thread scheduling purposes and lies dormant until one of four
 314      * things happens:
 315      *
 316      * <ul>
 317      * <li>Some other thread invokes {@link #unpark unpark} with the
 318      * current thread as the target; or
 319      *
 320      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
 321      * the current thread; or
 322      *
 323      * <li>The specified waiting time elapses; or
 324      *
 325      * <li>The call spuriously (that is, for no reason) returns.
 326      * </ul>
 327      *
 328      * <p>This method does <em>not</em> report which of these caused the
 329      * method to return. Callers should re-check the conditions which caused
 330      * the thread to park in the first place. Callers may also determine,
 331      * for example, the interrupt status of the thread, or the elapsed time
 332      * upon return.
 333      *
 334      * @param nanos the maximum number of nanoseconds to wait
 335      */
 336     public static void parkNanos(long nanos) {
 337         if (nanos > 0)
 338             UNSAFE.park(false, nanos);
 339     }
 340 
 341     /**
 342      * Disables the current thread for thread scheduling purposes, until
 343      * the specified deadline, unless the permit is available.
 344      *
 345      * <p>If the permit is available then it is consumed and the call
 346      * returns immediately; otherwise the current thread becomes disabled
 347      * for thread scheduling purposes and lies dormant until one of four
 348      * things happens:
 349      *
 350      * <ul>
 351      * <li>Some other thread invokes {@link #unpark unpark} with the
 352      * current thread as the target; or
 353      *
 354      * <li>Some other thread {@linkplain Thread#interrupt interrupts}
 355      * the current thread; or
 356      *
 357      * <li>The specified deadline passes; or
 358      *
 359      * <li>The call spuriously (that is, for no reason) returns.
 360      * </ul>
 361      *
 362      * <p>This method does <em>not</em> report which of these caused the
 363      * method to return. Callers should re-check the conditions which caused
 364      * the thread to park in the first place. Callers may also determine,
 365      * for example, the interrupt status of the thread, or the current time
 366      * upon return.
 367      *
 368      * @param deadline the absolute time, in milliseconds from the Epoch,
 369      *        to wait until
 370      */
 371     public static void parkUntil(long deadline) {
 372         UNSAFE.park(true, deadline);
 373     }
 374 
 375     /**
 376      * Returns the pseudo-randomly initialized or updated secondary seed.
 377      * Copied from ThreadLocalRandom due to package access restrictions
 378      */
 379     static final int nextSecondarySeed() {
 380         int r;
 381         Thread t = Thread.currentThread();
 382         if ((r = UNSAFE.getInt(t, SECONDARY)) != 0) {
 383             r ^= r << 13;   // xorshift
 384             r ^= r >>> 17;
 385             r ^= r << 5;
 386         }
 387         else if ((r = java.util.concurrent.ThreadLocalRandom.current().nextInt()) == 0)
 388             r = 1; // avoid zero
 389         UNSAFE.putInt(t, SECONDARY, r);
 390         return r;
 391     }
 392 
 393     // Hotspot implementation via intrinsics API
 394     private static final sun.misc.Unsafe UNSAFE;
 395     private static final long parkBlockerOffset;
 396     private static final long SEED;
 397     private static final long PROBE;
 398     private static final long SECONDARY;
 399     static {
 400         try {
 401             UNSAFE = sun.misc.Unsafe.getUnsafe();
 402             Class<?> tk = Thread.class;
 403             parkBlockerOffset = UNSAFE.objectFieldOffset
 404                 (tk.getDeclaredField("parkBlocker"));
 405             SEED = UNSAFE.objectFieldOffset
 406                 (tk.getDeclaredField("threadLocalRandomSeed"));
 407             PROBE = UNSAFE.objectFieldOffset
 408                 (tk.getDeclaredField("threadLocalRandomProbe"));
 409             SECONDARY = UNSAFE.objectFieldOffset
 410                 (tk.getDeclaredField("threadLocalRandomSecondarySeed"));
 411         } catch (Exception ex) { throw new Error(ex); }
 412     }
 413 
 414 }