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