* A reentrant mutual exclusion {@link Lock} with the same basic * behavior and semantics as the implicit monitor lock accessed using * {@code synchronized} methods and statements, but with extended * capabilities.
一个可重入的互斥锁,它与使用synchronized的方法和语句来进行隐式锁访问的方式具备相同的基本行为和语义,可是同时具备一些扩展功能。java
* <p>The constructor for this class accepts an optional * <em>fairness</em> parameter. When set {@code true}, under * contention, locks favor granting access to the longest-waiting * thread. Otherwise this lock does not guarantee any particular * access order. Programs using fair locks accessed by many threads * may display lower overall throughput (i.e., are slower; often much * slower) than those using the default setting, but have smaller * variances in times to obtain locks and guarantee lack of * starvation.
ReentrantLock构造方法接收一个可选的公平参数。当设置为true时,它是公平锁,这时锁会将访问权授予等待时间最长的线程。不然该锁将没法保证线程获取锁的访问顺序。公平锁与非公平锁相比,使用公平锁的程序会有较低的吞吐量,但使用公平锁能有效减小线程饥饿的发生。ui
使用建议:通常推荐的使用方式就是 lock()后紧跟try块,例如:this
class X { private final ReentrantLock lock = new ReentrantLock(); // ... public void m() { lock.lock(); // block until condition holds try { // ... method body } finally { lock.unlock() } } }}
private final Sync sync; /** * Base of synchronization control for this lock. Subclassed * into fair and nonfair versions below. Uses AQS state to * represent the number of holds on the lock. */ abstract static class Sync extends AbstractQueuedSynchronizer /** * Sync object for non-fair locks */ static final class NonfairSync extends Sync /** * Sync object for fair locks */ static final class FairSync extends Sync
以上为ReentrantLock提供的3个静态内部类,其中Sync类继承自AbstractQueuedSynchronizer(抽象队列同步器),而NonfairSync和FairSync为Sync类的两个实现,分别应用于非公平锁和公平锁的场景,而公平锁和非公平锁在释放锁的状况都是同样的,只是在获取锁时,公平锁会让等待最久的线程优先获取到锁,而非公平锁在获取锁时各线程机会均等,这样也就致使会出现饥饿现象产生.线程
static final class FairSync extends Sync final void lock() {acquire(1);}
static final class NonfairSync extends Sync { final void lock() { if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1); } }
以上为公平锁和非公平锁调用lock()的源码,其中的compareAndSetState,setExclusiveOwnerThread和acquire 均来自AQS中,有次能够看出非公平锁在lock时就会去尝试1次去获取锁,获取到了就返回,若是获取不到,则跟公平锁同样,调用acquire(arg)再次尝试获取锁,说白了,非公平锁比公平锁多1次抢占锁的动做。而在抢占动做中,非公平锁是直接尝试抢占,而公平锁会先判断是否位于头结点来决定是否抢占。code
非公平锁获取锁源码继承
final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) // overflow throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
公平锁获取锁源码队列
protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { setExclusiveOwnerThread(current); return true; } } else if (current == getExclusiveOwnerThread()) { int nextc = c + acquires; if (nextc < 0) throw new Error("Maximum lock count exceeded"); setState(nextc); return true; } return false; }
场景1 防止重复执行ci
ReentrantLock lock = new ReentrantLock(); if(lock.tryLock()){//若是已经被lock,则直接放回false,不会等待,达到忽略的效果 try { }finally { lock.unlock(); } }
场景2 串行执行(同步执行,相似synchronized)get
try { lock.lock(); }finally { lock.unlock(); }
场景3 超时等待同步
try{ if(lock.tryLock(5, TimeUnit.SECONDS)){ try { }finally { lock.unlock(); } } }catch (InterruptedException ex){ ex.printStackTrace(); }
场景4 响应中断
try { lock.lockInterruptibly(); } catch (InterruptedException ex) { ex.printStackTrace(); } finally { lock.unlock(); }