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/publicdomain/zero/1.0/ 5 */ 6 7 package java.util.concurrent.locks; 8 import sun.misc.Unsafe; 9 10 /** 11 * Basic thread blocking primitives for creating locks and other 12 * synchronization classes. 13 * 14 * <p>This class associates, with each thread that uses it, a permit 15 * (in the sense of the {@link java.util.concurrent.Semaphore 16 * Semaphore} class). A call to {@code park} will return immediately 17 * if the permit is available, consuming it in the process; otherwise 18 * it <em>may</em> block. A call to {@code unpark} makes the permit 19 * available, if it was not already available. (Unlike with Semaphores 20 * though, permits do not accumulate. There is at most one.) 21 * 22 * <p>Methods {@code park} and {@code unpark} provide efficient 23 * means of blocking and unblocking threads that do not encounter the 24 * problems that cause the deprecated methods {@code Thread.suspend} 25 * and {@code Thread.resume} to be unusable for such purposes: Races 26 * between one thread invoking {@code park} and another thread trying 27 * to {@code unpark} it will preserve liveness, due to the 28 * permit. Additionally, {@code park} will return if the caller's 29 * thread was interrupted, and timeout versions are supported. The 30 * {@code park} method may also return at any other time, for "no 31 * reason", so in general must be invoked within a loop that rechecks 32 * conditions upon return. In this sense {@code park} serves as an 33 * optimization of a "busy wait" that does not waste as much time 34 * spinning, but must be paired with an {@code unpark} to be 35 * effective. 36 * 37 * <p>The three forms of {@code park} each also support a 38 * {@code blocker} object parameter. This object is recorded while 39 * the thread is blocked to permit monitoring and diagnostic tools to 40 * identify the reasons that threads are blocked. (Such tools may 41 * access blockers using method {@link #getBlocker}.) The use of these 42 * forms rather than the original forms without this parameter is 43 * strongly encouraged. The normal argument to supply as a 44 * {@code blocker} within a lock implementation is {@code this}. 45 * 46 * <p>These methods are designed to be used as tools for creating 47 * higher-level synchronization utilities, and are not in themselves 48 * useful for most concurrency control applications. The {@code park} 49 * method is designed for use only in constructions of the form: 50 * 51 * <pre> {@code 52 * while (!canProceed()) { ... LockSupport.park(this); }}</pre> 53 * 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 public class LockSupport { 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 setBlocker(Thread t, Object arg)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 */ unpark(Thread thread)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 */ park(Object blocker)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} 175 * the current 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 */ parkNanos(Object blocker, long nanos)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 */ parkUntil(Object blocker, long deadline)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 * @param t the thread 250 * @return the blocker 251 * @throws NullPointerException if argument is null 252 * @since 1.6 253 */ getBlocker(Thread t)254 public static Object getBlocker(Thread t) { 255 if (t == null) 256 throw new NullPointerException(); 257 return unsafe.getObjectVolatile(t, parkBlockerOffset); 258 } 259 260 /** 261 * Disables the current thread for thread scheduling purposes unless the 262 * permit is available. 263 * 264 * <p>If the permit is available then it is consumed and the call 265 * returns immediately; otherwise the current thread becomes disabled 266 * for thread scheduling purposes and lies dormant until one of three 267 * things happens: 268 * 269 * <ul> 270 * 271 * <li>Some other thread invokes {@link #unpark unpark} with the 272 * current thread as the target; or 273 * 274 * <li>Some other thread {@linkplain Thread#interrupt interrupts} 275 * the current thread; or 276 * 277 * <li>The call spuriously (that is, for no reason) returns. 278 * </ul> 279 * 280 * <p>This method does <em>not</em> report which of these caused the 281 * method to return. Callers should re-check the conditions which caused 282 * the thread to park in the first place. Callers may also determine, 283 * for example, the interrupt status of the thread upon return. 284 */ park()285 public static void park() { 286 unsafe.park(false, 0L); 287 } 288 289 /** 290 * Disables the current thread for thread scheduling purposes, for up to 291 * the specified waiting time, unless the 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 four 296 * things happens: 297 * 298 * <ul> 299 * <li>Some other thread invokes {@link #unpark unpark} with the 300 * current thread as the target; or 301 * 302 * <li>Some other thread {@linkplain Thread#interrupt interrupts} 303 * the current thread; or 304 * 305 * <li>The specified waiting time elapses; or 306 * 307 * <li>The call spuriously (that is, for no reason) returns. 308 * </ul> 309 * 310 * <p>This method does <em>not</em> report which of these caused the 311 * method to return. Callers should re-check the conditions which caused 312 * the thread to park in the first place. Callers may also determine, 313 * for example, the interrupt status of the thread, or the elapsed time 314 * upon return. 315 * 316 * @param nanos the maximum number of nanoseconds to wait 317 */ parkNanos(long nanos)318 public static void parkNanos(long nanos) { 319 if (nanos > 0) 320 unsafe.park(false, nanos); 321 } 322 323 /** 324 * Disables the current thread for thread scheduling purposes, until 325 * the specified deadline, unless the permit is available. 326 * 327 * <p>If the permit is available then it is consumed and the call 328 * returns immediately; otherwise the current thread becomes disabled 329 * for thread scheduling purposes and lies dormant until one of four 330 * things happens: 331 * 332 * <ul> 333 * <li>Some other thread invokes {@link #unpark unpark} with the 334 * current thread as the target; or 335 * 336 * <li>Some other thread {@linkplain Thread#interrupt interrupts} 337 * the current thread; or 338 * 339 * <li>The specified deadline passes; or 340 * 341 * <li>The call spuriously (that is, for no reason) returns. 342 * </ul> 343 * 344 * <p>This method does <em>not</em> report which of these caused the 345 * method to return. Callers should re-check the conditions which caused 346 * the thread to park in the first place. Callers may also determine, 347 * for example, the interrupt status of the thread, or the current time 348 * upon return. 349 * 350 * @param deadline the absolute time, in milliseconds from the Epoch, 351 * to wait until 352 */ parkUntil(long deadline)353 public static void parkUntil(long deadline) { 354 unsafe.park(true, deadline); 355 } 356 } 357