/** * Acquires the lock. * * <p>If the lock is not available then the current thread becomes * disabled for thread scheduling purposes and lies dormant until the * lock has been acquired. * * <p><b>Implementation Considerations</b> * * <p>A {@code Lock} implementation may be able to detect erroneous use * of the lock, such as an invocation that would cause deadlock, and * may throw an (unchecked) exception in such circumstances. The * circumstances and the exception type must be documented by that * {@code Lock} implementation. * - 执行此方法时, 如果锁处于空闲状态, 当前线程将获取到锁. 相反, 如果锁已经被其他线程持有, * - 将禁用当前线程, 直到当前线程获取到锁 */ voidlock();
/** * Acquires the lock only if it is free at the time of invocation. * * <p>Acquires the lock if it is available and returns immediately * with the value {@code true}. * If the lock is not available then this method will return * immediately with the value {@code false}. * * <p>A typical usage idiom for this method would be: * <pre> {@code * Lock lock = ...; * if (lock.tryLock()) { * try { * // manipulate protected state * } finally { * lock.unlock(); * } * } else { * // perform alternative actions * }}</pre> * * This usage ensures that the lock is unlocked if it was acquired, and * doesn't try to unlock if the lock was not acquired. * * @return {@code true} if the lock was acquired and * {@code false} otherwise * - 如果锁可用, 则获取锁, 并立即返回 true, 否则返回 false. * - 与lock()的区别在于, tryLock()只是"试图"获取锁, 如果锁不可用, 不会导致当前线程被禁用, * - 当前线程仍然继续往下执行代码. * - 而 lock()方法则是一定要获取到锁, 如果锁不可用, 就一直等待, 在未获得锁之前,当前线程并不继续向下执行. */ booleantryLock();
/** * Releases the lock. * * <p><b>Implementation Considerations</b> * * <p>A {@code Lock} implementation will usually impose * restrictions on which thread can release a lock (typically only the * holder of the lock can release it) and may throw * an (unchecked) exception if the restriction is violated. * Any restrictions and the exception * type must be documented by that {@code Lock} implementation. * - 当前线程将释放持有的锁. 锁只能由持有者释放, 如果线程并不持有锁, 却执行该方法, 可能导致异常的发生 */ voidunlock();
/** * Returns a new {@link Condition} instance that is bound to this * {@code Lock} instance. * * <p>Before waiting on the condition the lock must be held by the * current thread. * A call to {@link Condition#await()} will atomically release the lock * before waiting and re-acquire the lock before the wait returns. * * <p><b>Implementation Considerations</b> * * <p>The exact operation of the {@link Condition} instance depends on * the {@code Lock} implementation and must be documented by that * implementation. * * @return A new {@link Condition} instance for this {@code Lock} instance * @throws UnsupportedOperationException if this {@code Lock} * implementation does not support conditions * - 条件对象,获取等待通知组件。该组件和当前的锁绑定, * - 当前线程只有获取了锁,才能调用该组件的 await()方法,而调用后,当前线程将释放锁 */ Condition newCondition();
/** * Queries the number of holds on this lock by the current thread. * * <p>A thread has a hold on a lock for each lock action that is not * matched by an unlock action. * * <p>The hold count information is typically only used for testing and * debugging purposes. For example, if a certain section of code should * not be entered with the lock already held then we can assert that * fact: * * <pre> {@code * class X { * ReentrantLock lock = new ReentrantLock(); * // ... * public void m() { * assert lock.getHoldCount() == 0; * lock.lock(); * try { * // ... method body * } finally { * lock.unlock(); * } * } * }}</pre> * * @return the number of holds on this lock by the current thread, * or zero if this lock is not held by the current thread * - 查询当前线程保持此锁的次数,也就是执行此线程执行lock方法的次数 */ publicintgetHoldCount(){ return sync.getHoldCount(); }
/** * Returns an estimate of the number of threads waiting to * acquire this lock. The value is only an estimate because the number of * threads may change dynamically while this method traverses * internal data structures. This method is designed for use in * monitoring of the system state, not for synchronization * control. * -- 返回正等待获取此锁的线程估计数,比如启动 10 个线程,1 个线程获得锁,此时返回的是 9 * * @return the estimated number of threads waiting for this lock */ publicfinalintgetQueueLength(){ return sync.getQueueLength(); }
/** * Returns an estimate of the number of threads waiting on the * given condition associated with this lock. Note that because * timeouts and interrupts may occur at any time, the estimate * serves only as an upper bound on the actual number of waiters. * This method is designed for use in monitoring of the system * state, not for synchronization control. * * @param condition the condition * @return the estimated number of waiting threads * @throws IllegalMonitorStateException if this lock is not held * @throws IllegalArgumentException if the given condition is * not associated with this lock * @throws NullPointerException if the condition is null * -- 返回等待与此锁相关的给定条件的线程估计数。 * -- 比如 10 个线程,用同一个 condition 对象, * -- 并且此时这 10 个线程都执行了 condition 对象的 await 方法,那么此时执行此方法返回 10 */ publicintgetWaitQueueLength(Condition condition){ if (condition == null) thrownew NullPointerException(); if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) thrownew IllegalArgumentException("not owner"); return sync.getWaitQueueLength((AbstractQueuedSynchronizer.ConditionObject)condition); }
/** * Queries whether any threads are waiting on the given condition * associated with this lock. Note that because timeouts and * interrupts may occur at any time, a {@code true} return does * not guarantee that a future {@code signal} will awaken any * threads. This method is designed primarily for use in * monitoring of the system state. * * @param condition the condition * @return {@code true} if there are any waiting threads * @throws IllegalMonitorStateException if this lock is not held * @throws IllegalArgumentException if the given condition is * not associated with this lock * @throws NullPointerException if the condition is null * -- 查询是否有线程等待与此锁有关的给定条件 * -- (condition),对于指定 contidion 对象,有多少线程执行了 condition.await 方法 */ publicbooleanhasWaiters(Condition condition){ if (condition == null) thrownew NullPointerException(); if (!(condition instanceof AbstractQueuedSynchronizer.ConditionObject)) thrownew IllegalArgumentException("not owner"); return sync.hasWaiters((AbstractQueuedSynchronizer.ConditionObject)condition); }
/** * Queries whether the given thread is waiting to acquire this * lock. Note that because cancellations may occur at any time, a * {@code true} return does not guarantee that this thread * will ever acquire this lock. This method is designed primarily for use * in monitoring of the system state. * * @param thread the thread * @return {@code true} if the given thread is queued waiting for this lock * @throws NullPointerException if the thread is null * -- 查询给定线程是否等待获取此锁 */ publicfinalbooleanhasQueuedThread(Thread thread){ return sync.isQueued(thread); }
/** * Queries whether any threads are waiting to acquire this lock. Note that * because cancellations may occur at any time, a {@code true} * return does not guarantee that any other thread will ever * acquire this lock. This method is designed primarily for use in * monitoring of the system state. * * @return {@code true} if there may be other threads waiting to * acquire the lock * -- 是否有线程等待锁 */ publicfinalbooleanhasQueuedThreads(){ return sync.hasQueuedThreads(); }
/** * Returns {@code true} if this lock has fairness set true. * * @return {@code true} if this lock has fairness set true * -- 该锁是否是公平锁 */ publicfinalbooleanisFair(){ return sync instanceof FairSync; }
/** * Queries if this lock is held by the current thread. * * <p>Analogous to the {@link Thread#holdsLock(Object)} method for * built-in monitor locks, this method is typically used for * debugging and testing. For example, a method that should only be * called while a lock is held can assert that this is the case: * * <pre> {@code * class X { * ReentrantLock lock = new ReentrantLock(); * // ... * * public void m() { * assert lock.isHeldByCurrentThread(); * // ... method body * } * }}</pre> * * <p>It can also be used to ensure that a reentrant lock is used * in a non-reentrant manner, for example: * * <pre> {@code * class X { * ReentrantLock lock = new ReentrantLock(); * // ... * * public void m() { * assert !lock.isHeldByCurrentThread(); * lock.lock(); * try { * // ... method body * } finally { * lock.unlock(); * } * } * }}</pre> * * @return {@code true} if current thread holds this lock and * {@code false} otherwise * -- 当前线程是否保持锁锁定,线程的执行 lock 方法的前后分别是 false 和 true */ publicbooleanisHeldByCurrentThread(){ return sync.isHeldExclusively(); }
/** * Queries if this lock is held by any thread. This method is * designed for use in monitoring of the system state, * not for synchronization control. * * @return {@code true} if any thread holds this lock and * {@code false} otherwise * --- 此锁是否有任意线程占用 */ publicbooleanisLocked(){ return sync.isLocked(); }
/** * * Acquires the lock only if it is not held by another thread at the time * of invocation.仅在调用时锁未被另一个线程保持的情况下,才获取该锁。 * 1)如果该锁没有被另一个线程保持,并且立即返回 true 值,则将锁的保持计数设置为 1。 * 即使已将此锁设置为使用公平排序策略,但是调用 tryLock() 仍将 立即获取锁(如果有可用的), * 而不管其他线程当前是否正在等待该锁。在某些情况下,此“闯入”行为可能很有用,即使它会打破公 * 平性也如此。如果希望遵守此锁的公平设置,则使用 tryLock(0, TimeUnit.SECONDS) * ,它几乎是等效的(也检测中断) * <p>Acquires the lock if it is not held by another thread and * returns immediately with the value {@code true}, setting the * lock hold count to one. Even when this lock has been set to use a * fair ordering policy, a call to {@code tryLock()} <em>will</em> * immediately acquire the lock if it is available, whether or not * other threads are currently waiting for the lock. * This "barging" behavior can be useful in certain * circumstances, even though it breaks fairness. If you want to honor * the fairness setting for this lock, then use * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } * which is almost equivalent (it also detects interruption). * 2)如果当前线程已经保持此锁,则将保持计数加 1,该方法将返回 true。 * <p>If the current thread already holds this lock then the hold * count is incremented by one and the method returns {@code true}. * 3)如果锁被另一个线程保持,则此方法将立即返回 false 值。 * <p>If the lock is held by another thread then this method will return * immediately with the value {@code false}. * return:如果锁是自由的并且被当前线程获取,或者当前线程已经保持该锁,则返回 true;否则返回 false * @return {@code true} if the lock was free and was acquired by the * current thread, or the lock was already held by the current * thread; and {@code false} otherwise */ publicbooleantryLock(){ return sync.nonfairTryAcquire(1); }
lock
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/** * Acquires the lock. * 1.如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为 1 * <p>Acquires the lock if it is not held by another thread and returns * immediately, setting the lock hold count to one. * 2.如果当前线程已经保持该锁,则将保持计数加 1,并且该方法立即返回 * <p>If the current thread already holds the lock then the hold * count is incremented by one and the method returns immediately. * 3.如果该锁被另一个线程保持,则出于线程调度的目的,禁用当前线程, * 并且在获得锁之前,该线程将一直处于休眠状态,此时锁保持计数被设置为 1 * <p>If the lock is held by another thread then the * current thread becomes disabled for thread scheduling * purposes and lies dormant until the lock has been acquired, * at which time the lock hold count is set to one. */ publicvoidlock(){ sync.lock(); }
/** * 1.如果当前线程未被中断,则获取锁。 * Acquires the lock unless the current thread is * {@linkplain Thread#interrupt interrupted}. * * 2.如果该锁没有被另一个线程保持,则获取该锁并立即返回,将锁的保持计数设置为 1。 * <p>Acquires the lock if it is not held by another thread and returns * immediately, setting the lock hold count to one. * * 3.如果当前线程已经保持此锁,则将保持计数加 1,并且该方法立即返回。 * <p>If the current thread already holds this lock then the hold count * is incremented by one and the method returns immediately. * * 4.如果锁被另一个线程保持,则出于线程调度目的,禁用当前线程,并且在发生以下两种情况之一以前,该线程将一直处于休眠状态: * <p>If the lock is held by another thread then the * current thread becomes disabled for thread scheduling * purposes and lies dormant until one of two things happens: * * <ul> * 4.1锁由当前线程获得 * <li>The lock is acquired by the current thread; or * 4.2其他某个线程中断当前线程 * <li>Some other thread {@linkplain Thread#interrupt interrupts} the * current thread. * * </ul> * 5.如果当前线程获得该锁,则将锁保持计数设置为 1,如果当前线程出现两种情况则抛出 InterruptedException,并且清除当前线程的已中断状态。 * <p>If the lock is acquired by the current thread then the lock hold * count is set to one. * * <p>If the current thread: * * <ul> * 5.1在进入此方法时已经设置了该线程的中断状态 * <li>has its interrupted status set on entry to this method; or * 5.2在等待获取锁的同时被中断 * <li>is {@linkplain Thread#interrupt interrupted} while acquiring * the lock, * * </ul> * * then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. * 6.在此实现中,因为此方法是一个显式中断点,所以要优先考虑响应中断,而不是响应锁的普通获取或重入获取 * <p>In this implementation, as this method is an explicit * interruption point, preference is given to responding to the * interrupt over normal or reentrant acquisition of the lock. * * @throws InterruptedException if the current thread is interrupted * -- 如果当前线程未被中断,获取锁 */ /** * lockInterruptibly()方法能够中断等待获取锁的线程。 * 当两个线程同时通过lock.lockInterruptibly()获取某个锁时,假若此时线程A获取到了锁,而线程B只有等待, * 那么对线程B调用threadB.interrupt()方法能够中断线程B的等待过程。 */ publicvoidlockInterruptibly()throws InterruptedException { sync.acquireInterruptibly(1); }
testInterruptedEnable:主线程获得了锁。。 testInterruptedEnable:子线程开始:。。。 testInterruptedEnable:子线程thread开始中断。。 testInterruptedEnable:子线程等待锁的过程被中断 testInterruptedEnable:子线程获得了锁。。 java.lang.InterruptedException at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898) at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222) at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335) at com.sunld.thread.lock.ReentrantLockInterruptedTest.lambda$testInterruptedEnable$0(ReentrantLockInterruptedTest.java:18) at java.lang.Thread.run(Thread.java:748) Exception in thread "可中断线程!!" java.lang.IllegalMonitorStateException at java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:151) at java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1261) at java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:457) at com.sunld.thread.lock.ReentrantLockInterruptedTest.lambda$testInterruptedEnable$0(ReentrantLockInterruptedTest.java:26) at java.lang.Thread.run(Thread.java:748)