📄 abstractqueuedsynchronizer.java
字号:
* to signal it, so it can safely park */ return true; if (s > 0) { /* * Predecessor was cancelled. Skip over predecessors and * indicate retry. */ do { node.prev = pred = pred.prev; } while (pred.waitStatus > 0); pred.next = node; } else /* * Indicate that we need a signal, but don't park yet. Caller * will need to retry to make sure it cannot acquire before * parking. */ compareAndSetWaitStatus(pred, 0, Node.SIGNAL); return false; } /** * Convenience method to interrupt current thread. */ private static void selfInterrupt() { Thread.currentThread().interrupt(); } /** * Convenience method to park and then check if interrupted * @return true if interrupted */ private static boolean parkAndCheckInterrupt() { LockSupport.park(); return Thread.interrupted(); } /* * Various flavors of acquire, varying in exclusive/shared and * control modes. Each is mostly the same, but annoyingly * different. Only a little bit of factoring is possible due to * interactions of exception mechanics (including ensuring that we * cancel if tryAcquire throws exception) and other control, at * least not without hurting performance too much. */ /** * Acquire in exclusive uninterruptible mode for thread already in * queue. Used by condition wait methods as well as acquire. * @param node the node * @param arg the acquire argument * @return true if interrupted while waiting */ final boolean acquireQueued(final Node node, int arg) { try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC return interrupted; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } } /** * Acquire in exclusive interruptible mode * @param arg the acquire argument */ private void doAcquireInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.EXCLUSIVE); try { for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC return; } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) break; } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } // Arrive here only if interrupted cancelAcquire(node); throw new InterruptedException(); } /** * Acquire in exclusive timed mode * @param arg the acquire argument * @param nanosTimeout max wait time * @return true if acquired */ private boolean doAcquireNanos(int arg, long nanosTimeout) throws InterruptedException { long lastTime = System.nanoTime(); final Node node = addWaiter(Node.EXCLUSIVE); try { for (;;) { final Node p = node.predecessor(); if (p == head && tryAcquire(arg)) { setHead(node); p.next = null; // help GC return true; } if (nanosTimeout <= 0) { cancelAcquire(node); return false; } if (shouldParkAfterFailedAcquire(p, node)) { LockSupport.parkNanos(nanosTimeout); if (Thread.interrupted()) break; long now = System.nanoTime(); nanosTimeout -= now - lastTime; lastTime = now; } } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } // Arrive here only if interrupted cancelAcquire(node); throw new InterruptedException(); } /** * Acquire in shared uninterruptible mode * @param arg the acquire argument */ private void doAcquireShared(int arg) { final Node node = addWaiter(Node.SHARED); try { boolean interrupted = false; for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg); if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC if (interrupted) selfInterrupt(); return; } } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) interrupted = true; } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } } /** * Acquire in shared interruptible mode * @param arg the acquire argument */ private void doAcquireSharedInterruptibly(int arg) throws InterruptedException { final Node node = addWaiter(Node.SHARED); try { for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg); if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC return; } } if (shouldParkAfterFailedAcquire(p, node) && parkAndCheckInterrupt()) break; } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } // Arrive here only if interrupted cancelAcquire(node); throw new InterruptedException(); } /** * Acquire in shared timed mode * @param arg the acquire argument * @param nanosTimeout max wait time * @return true if acquired */ private boolean doAcquireSharedNanos(int arg, long nanosTimeout) throws InterruptedException { long lastTime = System.nanoTime(); final Node node = addWaiter(Node.SHARED); try { for (;;) { final Node p = node.predecessor(); if (p == head) { int r = tryAcquireShared(arg); if (r >= 0) { setHeadAndPropagate(node, r); p.next = null; // help GC return true; } } if (nanosTimeout <= 0) { cancelAcquire(node); return false; } if (shouldParkAfterFailedAcquire(p, node)) { LockSupport.parkNanos(nanosTimeout); if (Thread.interrupted()) break; long now = System.nanoTime(); nanosTimeout -= now - lastTime; lastTime = now; } } } catch (RuntimeException ex) { cancelAcquire(node); throw ex; } // Arrive here only if interrupted cancelAcquire(node); throw new InterruptedException(); } // Main exported methods /** * Attempts to acquire in exclusive mode. This method should query * if the state of the object permits it to be acquired in the * exclusive mode, and if so to acquire it. * * <p>This method is always invoked by the thread performing * acquire. If this method reports failure, the acquire method * may queue the thread, if it is not already queued, until it is * signalled by a release from some other thread. This can be used * to implement method {@link Lock#tryLock()}. * * <p>The default * implementation throws {@link UnsupportedOperationException} * * @param arg the acquire argument. This value * is always the one passed to an acquire method, * or is the value saved on entry to a condition wait. * The value is otherwise uninterpreted and can represent anything * you like. * @return true if successful. Upon success, this object has been * acquired. * @throws IllegalMonitorStateException if acquiring would place * this synchronizer in an illegal state. This exception must be * thrown in a consistent fashion for synchronization to work * correctly. * @throws UnsupportedOperationException if exclusive mode is not supported */ protected boolean tryAcquire(int arg) { throw new UnsupportedOperationException(); } /** * Attempts to set the state to reflect a release in exclusive * mode. <p>This method is always invoked by the thread * performing release. * * <p>The default implementation throws * {@link UnsupportedOperationException} * @param arg the release argument. This value * is always the one passed to a release method, * or the current state value upon entry to a condition wait. * The value is otherwise uninterpreted and can represent anything * you like. * @return <tt>true</tt> if this object is now in a fully released state, * so that any waiting threads may attempt to acquire; and <tt>false</tt> * otherwise. * @throws IllegalMonitorStateException if releasing would place * this synchronizer in an illegal state. This exception must be * thrown in a consistent fashion for synchronization to work * correctly. * @throws UnsupportedOperationException if exclusive mode is not supported */ protected boolean tryRelease(int arg) { throw new UnsupportedOperationException(); } /** * Attempts to acquire in shared mode. This method should query if * the state of the object permits it to be acquired in the shared * mode, and if so to acquire it. * * <p>This method is always invoked by the thread performing * acquire. If this method reports failure, the acquire method * may queue the thread, if it is not already queued, until it is * signalled by a release from some other thread. * * <p>The default implementation throws {@link * UnsupportedOperationException} * * @param arg the acquire argument. This value * is always the one passed to an acquire method, * or is the value saved on entry to a condition wait. * The value is otherwise uninterpreted and can represent anything * you like. * @return a negative value on failure, zero on exclusive success, * and a positive value if non-exclusively successful, in which * case a subsequent waiting thread must check * availability. (Support for three different return values * enables this method to be used in contexts where acquires only * sometimes act exclusively.) Upon success, this object has been * acquired. * @throws IllegalMonitorStateException if acquiring would place * this synchronizer in an illegal state. This exception must be * thrown in a consistent fashion for synchronization to work * correctly. * @throws UnsupportedOperationException if shared mode is not supported */ protected int tryAcquireShared(int arg) { throw new UnsupportedOperationException(); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -