Java并发ReentrantLock

ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁。

重入性

表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻塞。关键字synchronized隐式支持重入性 ,synchronized通过获取自增,释放自减的方式实现重入。

  1. 在线程获取锁的时候,如果已经获取锁的线程是当前线程的话则直接再次获取成功
  2. 由于锁会被获取n次,那么只有锁在被释放同样的n次之后,该锁才算是完全释放成功

每次获取都会对同步状态进行加一的操作。检查占有线程是否为当前线程,如果是的话,同步状态加1,直接返回,保证了重入性。释放锁的时候,同步状态减1。重入锁的释放必须得等到同步状态为0时锁才算成功释放,否则锁仍未释放。如果锁被获取n次,释放了n-1次,该锁未完全释放返回false,只有被释放n次才算成功释放,返回true。

公平锁和非公平锁

公平性,是针对获取锁而言的,如果一个锁是公平的,那么锁的获取顺序就应该符合请求上的绝对时间顺序,满足FIFO。构造函数传入true,创建公平锁。

公平锁获取锁时,需要判断当前节点在同步队列中是否有前驱节点的判断,如果有前驱节点说明有线程比当前线程更早的请求资源,根据公平性,当前线程请求资源失败。

公平锁每次获取到锁为同步队列中的第一个节点,保证请求资源时间上的绝对顺序,而非公平锁有可能刚释放锁的线程下次继续获取该锁,则有可能导致其他线程永远无法获取到锁,造成“饥饿”现象

公平锁为了保证时间上的绝对顺序,需要频繁的上下文切换,而非公平锁会降低一定的上下文切换,降低性能开销。因此,ReentrantLock默认选择的是非公平锁,则是为了减少一部分上下文切换,保证了系统更大的吞吐量

参考:

彻底理解ReentrantLock