Java 基础教程

Java 面向对象

Java 高级教程

Java 笔记

Java ReentrantLock 使用方法

Java 锁 Java 锁


Java 从 1.5 版本开始提供了 Lock 接口,主要是抽象锁相关的操作行为,其主要实现为 ReentrantLock,也是最常用的锁的实现类,和 synchronized 一样,它也是可重入锁,而且还可以实现公平锁机制。

Lock 接口

Lock 接口位于 java.util.concurrent.locks 下,其接口定义如下:

public interface Lock {

    void lock();

    void lockInterruptibly() throws InterruptedException;

    boolean tryLock();

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

    void unlock();

    Condition newCondition();
}

其中:

  • lock():获取锁的方法,它会阻塞程序,直到成功地获取锁。
  • lockInterruptibly():与 lock() 不同的地方是,它可以响应程序中断,如果被其他程序中断了,则抛出 InterruptedException
  • tryLock():尝试获取锁,该方法会立即返回,并不会阻塞程序。如果获取锁成功,则返回 true,反之,则返回 false。
  • tryLock(long time, TimeUnit unit):尝试获取锁,如果能获取锁,则直接返回 true;否则,阻塞等待,阻塞时长由传入的参数来决定,在等待时,如果发生了中断,则抛出 InterruptedException;如果在等待的时间中获取了锁,则返回 true,反之返回 false。
  • unlock():释放锁的方法,通常放在 finally 代码块里。
  • newCondition():新建一个条件,一个 Lock 可以关联多个条件。

ReentrantLock 使用

JDK 给出的示例如下:

class X {

     private final ReentrantLock lock = new ReentrantLock();
     // ...

     public void m() {
       lock.lock();  // block until condition holds
       try {
         // ... method body
       } finally {
         lock.unlock()
       }
     }
}

需要注意的是,加锁的过程 lock.lock(); 放在了 try 的外部,这主要是如果放在 try 内部,如果获取锁操作失败,也都会执行释放锁操作(lock.unlock),但是由于当前线程加锁失败并没有持有 lock 对象锁,所以程序会抛出异常。