• Java Concurrency


    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 中的元素没有特定的顺序。

  • 相关阅读:
    c++ 设计模式3 (重构技法 Template Method)
    C++ 设计模式2 (面向对象设计原则)
    c++ 设计模式1
    算法总结—二分搜索与旋转排序数组
    c++ 构造函数,拷贝构造函数,析构函数与赋值操作符
    题解 P2330 【[SCOI2005]繁忙的都市】
    题解 CF896C 【Willem, Chtholly and Seniorious】
    题解 P3369 【【模板】普通平衡树】
    题解 CF383C 【Propagating tree】
    题解 P1179 【数字统计】
  • 原文地址:https://www.cnblogs.com/huey/p/6004214.html
Copyright © 2020-2023  润新知