ReentrantLock是一个可重入锁,Reentrant就是可重入的意思
ReentrantLock使用需要先实例化一个ReentrantLock对象
这个对象有三种方法
lock(),unlock(),trylock();
lock就是加锁,unlock是解锁,加锁和解锁之间的代码块就是被加锁的区域,ReentrantLock需要手动解锁
ReentrantLock reentrantlock =new ReentrantLock();
reentrantlock.lock();
//代码块内容
reentrantlock.unlock();
(1)忘记unlock的问题
在实际的编程中,代码往往有很多分支,调用了lock之后必须要调用unlock其他地方才能调用lock加锁,但是由于需要手动解锁,所以很有可能忘了unlock,为保证每个lock都能被unlock,使用trycatch中的finally代码块来确保最后都会释放锁。
ReentrantLock reentrantlock =new ReentrantLock();
try{
reentrantlock。lock();
//分支语句
}finally{
reentrantlock.unlock();
}
(2)trylock()方法
普通的lock方法如果有其他线程已经lock了,那线程就会阻塞并死等,但是使用trylock方法,就只会尝试加锁,然后返回true或者false来表明是否加锁成功,加锁失败就放弃加锁,也不死等。
trylock方法还可以传入时间作为参数,此时再尝试加锁如果失败就会等待传入的时间,然后再次再次尝试加锁,加锁还是失败就放弃加锁。
因为加锁成功和加锁失败后肯定是两套不同的流程,所以在trylock之后,需要判断一下是否加锁成功,成功就需要释放锁,失败就不需要。
(3)提供了公平锁的版本
实例化ReentrantLock时可以传入true,就代表实例化的锁是公平锁,不传参数或者传入false,锁就是不公平锁。
(4)ReentrantLock和synchronized的区别
1.ReentrantLock是java代码实现的类,synchronized是jvm底层c++实现的关键字,两者加锁的方式不同,ReentrantLock和synchronized不会存在锁竞争。
2.synchronized是非公平锁,ReentrantLock默认是非公平锁,但是可以传入true参数创建公平锁。
3.synchronized是自动释放锁,ReentrantLock是手动释放锁,更自由,但是容易忘记释放。
4.ReentrantLock有更强大的唤醒机制,可以使用搭配使用condition使等待唤醒特定的线程。
5.synchronized在申请失败时,会死等,ReentrantLock的trylock不会死等。