Java并发19:Lock系列-Lock接口基本方法学习实例

本章主要通过解读Lock接口的源码,来学习Lock接口定义的方法的使用。

1.源码注释

Lock接口,定义了如下方法:

/**
 * Lock接口
 * @since 1.5
 * @author Doug Lea
 */
public interface Lock {

    /**
     * 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.
     */
    void lock();

    /**
     * Acquires the lock unless the current thread is
     * {@linkplain Thread#interrupt interrupted}.
     *
     * <p>Acquires the lock if it is available and returns immediately.
     *
     * <p>If the lock is not available then the current thread becomes
     * disabled for thread scheduling purposes and lies dormant until
     * one of two things happens:
     *
     * <ul>
     * <li>The lock is acquired by the current thread; or
     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
     * current thread, and interruption of lock acquisition is supported.
     * </ul>
     *
     * <p>If the current thread:
     * <ul>
     * <li>has its interrupted status set on entry to this method; or
     * <li>is {@linkplain Thread#interrupt interrupted} while acquiring the
     * lock, and interruption of lock acquisition is supported,
     * </ul>
     * then {@link InterruptedException} is thrown and the current thread‘s
     * interrupted status is cleared.
     */
    void lockInterruptibly() throws InterruptedException;

    /**
     * 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
     */
    boolean tryLock();

    /**
     * Acquires the lock if it is free within the given waiting time and the
     * current thread has not been {@linkplain Thread#interrupt interrupted}.
     *
     * <p>If the lock is available this method returns immediately
     * with the value {@code true}.
     * If the lock is not available then
     * the current thread becomes disabled for thread scheduling
     * purposes and lies dormant until one of three things happens:
     * <ul>
     * <li>The lock is acquired by the current thread; or
     * <li>Some other thread {@linkplain Thread#interrupt interrupts} the
     * current thread, and interruption of lock acquisition is supported; or
     * <li>The specified waiting time elapses
     * </ul>
     *
     * <p>If the lock is acquired then the value {@code true} is returned.
     *
     * <p>If the current thread:
     * <ul>
     * <li>has its interrupted status set on entry to this method; or
     * <li>is {@linkplain Thread#interrupt interrupted} while acquiring
     * the lock, and interruption of lock acquisition is supported,
     * </ul>
     * then {@link InterruptedException} is thrown and the current thread‘s
     * interrupted status is cleared.
     *
     * <p>If the specified waiting time elapses then the value {@code false}
     * is returned.
     * If the time is
     * less than or equal to zero, the method will not wait at all.
     */
    boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

    /**
     * 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.
     */
    void unlock();

    /**
     * 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.
     */
    Condition newCondition();
}

2.源码解读

通过解读上面的源码,将Lock接口提供的方法总结如下:

1. void lock();

  • 尝试去获得锁。
  • 如果锁不可用,则为了线程调度的目的,当前线程会变得不可用,直到获得锁为止。

2.void lockInterruptibly() throws InterruptedException;

  • 尝试去获得锁,除非当前线程被中断。
  • 如果锁不可用,则为了线程调度的目的,当前线程会变得不可用,直到出现以下两种情况之一:
  1. 当前线程获取锁。
  2. 其他的线程中断了这个线程。
  • 如果当前线程在获取锁操作中,被其他线程中断,则会抛出InterruptedException异常,并且将中断标识清除。

3.boolean tryLock();

  • 只有在调用时锁是空闲的,才获取锁。
  • 如果锁空闲,则获取锁,并立即返回true值。
  • 如果锁不可用,则立即返回false值。
  • tryLock()方法的典型使用方式如下:
Lock lock = ...;
if (lock.tryLock()) {//如果锁空闲,就获取锁
  try {
    // manipulate protected state
  } finally {
    lock.unlock();//获取了锁就要记得释放
  }
} else {//没获取锁,那就干点别的
  // perform alternative actions
}
  • 上述方式能够保证:如果获取了锁能够释放锁;如果没获取锁,也不会去尝试释放锁。

4.boolean tryLock(long time, TimeUnit unit) throws InterruptedException;

  • 如果在限定时间内,锁可用并且当前线程不被中断,则获取锁。
  • 如果锁空闲,则获取锁,并立即返回true值。
  • 如果锁不可用,则为了线程调度的目的,当前线程会变得不可用,直到出现以下三种情况之一:
  1.  当前线程获取锁。
  2. 其他的线程中断了这个线程。
  3. 限定时间超时。
  • 针对上面三种情况,当前方法会分别作出以下操作:
  1. 如果获得锁,则即返回true值。
  2. 如果当前线程在获取锁操作中,被其他线程中断,则会抛出InterruptedException异常,并且将中断标识清除。
  3. 如果限定时间超时,则即返回false值。

5.void unlock();

  • 解锁,或者叫释放锁。
  • 通常这样释放锁:

 

Java并发19:Lock系列-Lock接口基本方法学习实例

上一篇:python词典的items()用法


下一篇:多个JAR包合并成一个