GNU Classpath (0.98) | |
Frames | No Frames |
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: }
GNU Classpath (0.98) |