ReentrantLock重入锁
java.util.concurrent.locks包提供的ReentrantLock用于替代synchronized加锁
Categories:
重入性
重入性指当线程需要再次获取同一把锁时, 不会因为自身而造成死锁, 锁的本质是作用于代码块或方法,而不是线程的整个执行上下文。即使线程已经持有锁,进入新的同步方法或代码块时,仍然需要执行获取锁的操作,确保锁的计数正确。
所以支持重入性应该解决下列问题
- 由于获得多次相同的锁, 需要计数以释放相同次数
- 相同线程再次获取锁应当直接成功, 防止死锁
为什么需要ReentrantLock
Java语言直接提供了synchronized
关键字用于加锁,但这种锁一是很重,二是获取时必须一直等待,没有额外的尝试机制。
if (lock.tryLock(1, TimeUnit.SECONDS)) {
try {
...
} finally {
lock.unlock();
}
}
java.util.concurrent.locks
包提供的ReentrantLock
用于替代synchronized
加锁
尝试获取锁的时候,最多等待1秒。如果1秒后仍未获取到锁,tryLock()
返回false
,程序就可以做一些额外处理,而不是无限等待下去。
所以,使用ReentrantLock
比直接使用synchronized
更安全,线程在tryLock()
失败的时候不会导致死锁。
ReentrantLock使用
public class Counter {
//和关键字不同, 需要获得一个重入锁对象
private final Lock lock = new ReentrantLock();
private int count;
public void add(int n) {
//代码块加锁
lock.lock();
try {
count += n;
} finally {
//在finally中解锁
lock.unlock();
}
}
}