Java Concurrency - ReentrantLock

ReentrantLock 是可重入的互斥锁,它具有与使用 synchronized 方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。

ReentrantLock 将由最近成功获得锁,并且还没有释放该锁的线程所拥有。当锁没有被另一个线程所拥有时,调用 lock 方法的线程将成功获取该锁并返回。如果当前线程已经拥有该锁,此方法将立即返回。

此类的构造方法接受一个可选的 fairness 参数。当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间最长的线程。否则此锁将无法保证任何特定访问顺序。与采用默认设置(使用不公平锁)相比,使用公平锁的程序在许多线程访问时表现为很低的总体吞吐量(即速度很慢,常常极其慢),但是在获得锁和保证锁分配的均衡性时差异较小。不过要注意的是,公平锁不能保证线程调度的公平性。因此,使用公平锁的众多线程中的一员可能获得多倍的成功机会,这种情况发生在其他活动线程没有被处理并且目前并未持有锁时。还要注意的是,未定时的 tryLock 方法并没有使用公平设置。因为即使其他线程正在等待,只要该锁是可用的,此方法就可以获得成功。

建议在调用 lock 方法后总是立即接着使用 try 块。典型的代码如下:

class X {
    private final ReentrantLock lock = new ReentrantLock();
    // ...

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

除了实现 Lock 接口,此类还定义了 isLocked 和 getLockQueueLength 方法,以及一些相关的 protected 访问方法,这些方法对检测和监视可能很有用。

该类的序列化与内置锁的行为方式相同:一个反序列化的锁处于解除锁定状态,不管它被序列化时的状态是怎样的。

 

ReentrantLock 的方法

getHoldCount()

查询当前线程保持此锁的次数。

对于与解除锁操作不匹配的每个锁操作,线程都会保持一个锁。

保持计数信息通常只用于测试和调试。例如,如果不应该使用已经保持的锁进入代码的某一部分,则可以声明如下:

class X {
    ReentrantLock lock = new ReentrantLock();
    // ...     
    public void m() { 
        assert lock.getHoldCount() == 0;
        lock.lock();
        try {
            // ... method body
        } finally {
            lock.unlock();
        }
    }
}

isHeldByCurrentThread()

查询当前线程是否保持此锁。

与内置监视器锁的 Thread.holdsLock(java.lang.Object) 方法类似,此方法通常用于调试和测试。例如,只在保持某个锁时才应调用的方法可以声明如下:

class X {
    ReentrantLock lock = new ReentrantLock();
    // ...

    public void m() { 
        assert lock.isHeldByCurrentThread();
        // ... method body
    }
}

还可以用此方法来确保某个重入锁是否以非重入方式使用的,例如:

class X {
    ReentrantLock lock = new ReentrantLock();
    // ...

    public void m() { 
        assert !lock.isHeldByCurrentThread();
        lock.lock();
        try {
            // ... method body
        } finally {
            lock.unlock();
        }
    }
}

isLocked()

查询此锁是否由任意线程保持。此方法用于监视系统状态,不用于同步控制。

isFair()

如果此锁的公平设置为 true,则返回 true。

getOwner()

返回目前拥有此锁的线程,如果此锁不被任何线程拥有,则返回 null。

hasQueuedThreads()

查询是否有些线程正在等待获取此锁。注意,因为随时可能发生取消,所以返回 true 并不保证有其他线程将获取此锁。此方法主要用于监视系统状态。

hasQueuedThread(Thread thread)

查询给定线程是否正在等待获取此锁。注意,因为随时可能发生取消,所以返回 true 并不保证此线程将获取此锁。此方法主要用于监视系统状态。

getQueueLength()

返回正等待获取此锁的线程估计数。该值仅是估计的数字,因为在此方法遍历内部数据结构的同时,线程的数目可能动态地变化。此方法用于监视系统状态,不用于同步控制。

getQueuedThreads()

返回一个 collection,它包含可能正等待获取此锁的线程。因为在构造此结果的同时实际的线程池可能动态地变化,所以返回的 collection 仅是尽力的估计值。所返回 collection 中的元素没有特定的顺序。

hasWaiters(Condition condition)

查询是否有些线程正在等待与此锁有关的给定条件。注意,因为随时可能发生超时和中断,所以返回 true 并不保证将来某个 signal 将唤醒线程。此方法主要用于监视系统状态。

getWaitQueueLength(Condition condition)

返回等待与此锁相关的给定条件的线程估计数。注意,因为随时可能发生超时和中断,所以只能将估计值作为实际等待线程数的上边界。此方法用于监视系统状态,不用于同步控制。

getWaitingThreads(Condition condition)

返回一个 collection,它包含可能正在等待与此锁相关给定条件的那些线程。因为在构造此结果的同时实际的线程池可能动态地变化,所以返回 collection 的元素只是尽力的估计值。所返回 collection 中的元素没有特定的顺序。

 

posted on 2016-10-27 15:51  huey2672  阅读(217)  评论(0编辑  收藏  举报