java reentrantlock是什么?一起来看下吧:
是一个可重入且独占式的锁,它具有与使用synchronized监视器锁相同的基本行为和语义,但与synchronized关键字相比,它更灵活、更强大,增加了轮询、超时、中断等高级功能。ReentrantLock,顾名思义,它是支持可重入锁的锁,是一种递归无阻塞的同步机制。除此之外,该锁还支持获取锁时的公平和非公平选择。
ReentrantLock的内部类Sync继承了AQS,分为公平锁FairSync和非公平锁NonfairSync。如果在绝对时间上,先对锁进行获取的请求你一定先被满足,那么这个锁是公平的,反之,是不公平的。公平锁的获取,也就是等待时间最长的线程最优先获取锁,也可以说锁获取是顺序的。ReentrantLock的公平与否,可以通过它的构造函数来决定。
事实上,公平锁往往没有非公平锁的效率高,但是,并不是任何场景都是以TPS作为唯一指标,公平锁能够减少“饥饿”发生的概率,等待越久的请求越能够得到优先满足。
ReentrantLock是通过自定义同步器来实现锁的获取与释放,我们以非公平锁(默认)实现为例,对锁的获取和释放进行详解。
获取锁:
public ReentrantLock() { sync = new NonfairSync(); }
即内部同步组件为非公平锁,获取锁的代码为:
public void lock() { sync.lock(); }
释放锁:
成功获取锁的线程在完成业务逻辑之后,需要调用unlock()来释放锁:
public void unlock() { sync.release(1); }
unlock()调用NonfairSync类的release(int)方法释放锁,release(int)方法是定义在AQS中的方法:
public final boolean release(int arg) { if (tryRelease(arg)) { Node h = head; if (h != null && h.waitStatus != 0) unparkSuccessor(h); return true; } return false; }
tryRelease(int)是子类需要实现的方法:
protected final boolean tryRelease(int releases) { // 计算新的状态值 int c = getState() - releases; // 判断当前线程是否是持有锁的线程,如果不是的话,抛出异常 if (Thread.currentThread() != getExclusiveOwnerThread()) throw new IllegalMonitorStateException(); boolean free = false; // 新的状态值是否为0,若为0,则表示该锁已经完全释放了,其他线程可以获取同步状态了 if (c == 0) { free = true; setExclusiveOwnerThread(null); } // 更新状态值 setState(c); return free; }
如果该锁被获取n次,那么前(n-1)次tryRelease(int)方法必须返回false,只有同步状态完全释放了,才能返回true。可以看到,该方法将同步状态是否为0作为最终释放的条件,当状态为0时,将占有线程设为null,并返回true,表示释放成功。
以上就是小编今天的分享,希望可以帮助到大家。