今天是:
带着程序的旅程,每一行代码都是你前进的一步,每个错误都是你成长的机会,最终,你将抵达你的目的地。
title

ReentrantLock

概述

ReentrantLock 是一种可重入的互斥锁,具有与使用 synchronized 方法和语句访问的隐式监视器锁相同的基本行为和语义,但具有扩展功能。 ReentrantLock 由上一个成功锁定但尚未解锁的线程拥有。当锁未被另一个线程拥有时,调用 lock 的线程将成功获取锁并返回。如果当前线程已经拥有该锁,则该方法将立即返回。可以使用 isHeldByCurrentThread 和 getHoldCount 方法检查此情况。 此类的构造函数接受一个可选的公平参数。在发生竞争时设置为 true 时,锁优先考虑授予最长等待线程的访问权。否则,此锁不保证任何特定的访问顺序。使用许多线程访问的公平锁的程序可能显示出较低的总吞吐量(即较慢;通常要慢得多),但具有较小的获取锁的时间差异和保证缺乏饥饿的可能性。但是,请注意,锁的公平性并不保证线程调度的公平性。因此,使用公平锁的许多线程之一可能在连续多次获得它,而其他活动线程并未进行并当前未持有该锁。另请注意,未定时的 tryLock()方法不遵守公平设置。如果锁可用,即使其他线程正在等待,它也会成功。 建议的做法是总是在调用 lock 之后立即使用 try 块,通常是在 before/after 结构中,如下所示:

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

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

除了实现 Lock 接口外,此类还定义了许多用于检查锁状态的公共和保护方法。其中一些方法仅对工具和监控有用。 此类的序列化行为与内置锁的行为相同:反序列化的锁在解锁状态,而不管在序列化时的状态如何。 此锁支持同一线程的最多 2147483647 个递归锁。尝试超过此限制将导致锁定方法抛出 Error。

同步方式主要由 继承 AbstractQueuedSynchronizer的Sync实现,同时实现的公平锁和非公平锁

公平锁和非公平锁

在加锁的时候会先调用initialTryLock方法,对于公平锁来说要判断它前面有没有排队的线程才有可能获取到锁,非公平锁的情况先来尝试下获取锁,苏果获取不到才加入到队列

final void lock() {
    if (!initialTryLock())
        acquire(1);
}

 

    static final class NonfairSync extends Sync {
        private static final long serialVersionUID = 7316153563782823691L;

        final boolean initialTryLock() {
            Thread current = Thread.currentThread();
            if (compareAndSetState(0, 1)) { // first attempt is unguarded
                setExclusiveOwnerThread(current);
                return true;
            } else if (getExclusiveOwnerThread() == current) {
                int c = getState() + 1;
                if (c < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(c);
                return true;
            } else
                return false;
        }

        /**
         * Acquire for non-reentrant cases after initialTryLock prescreen
         */
        protected final boolean tryAcquire(int acquires) {
            if (getState() == 0 && compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }
    }
公平锁

    /**
     * Sync object for fair locks
     */
    static final class FairSync extends Sync {
        private static final long serialVersionUID = -3000897897090466540L;

        /**
         * Acquires only if reentrant or queue is empty.
         */
        final boolean initialTryLock() {
            Thread current = Thread.currentThread();
            int c = getState();
            if (c == 0) {
                if (!hasQueuedThreads() && compareAndSetState(0, 1)) {
                    setExclusiveOwnerThread(current);
                    return true;
                }
            } else if (getExclusiveOwnerThread() == current) {
                if (++c < 0) // overflow
                    throw new Error("Maximum lock count exceeded");
                setState(c);
                return true;
            }
            return false;
        }

        /**
         * Acquires only if thread is first waiter or empty
         */
        protected final boolean tryAcquire(int acquires) {
            if (getState() == 0 && !hasQueuedPredecessors() &&
                compareAndSetState(0, acquires)) {
                setExclusiveOwnerThread(Thread.currentThread());
                return true;
            }
            return false;
        }
    }

使用场景

 

分享到:

专栏

类型标签

网站访问总量