一、ReentantLock
1.概念
ReentantLock的意思是”可重入互斥锁“,是一个类,在jvm外部实现的。和synchronized定位类似,都是用来实现互斥效果,保证线程安全。
2.ReentrantLock的用法
①lock():加锁,如果获取不到锁就死等。
②trylock(超时时间):加锁,如果获取不到锁,等待一段时间之后就放弃加锁。(加锁成功,没啥特殊;枷锁失败,不会阻塞等待,直接返回false)
③unlock():解锁
3.代码示例
ReentrantLock lock1=new ReentrantLock();
lock1.lock();
try{
//write something
}finally{
lock.unlock()
}
二、ReentrantLock 和 synchronized 的区别
①synchronized 是一个关键字, 是 JVM 内部实现的(大概率是基于 C++ 实现);ReentrantLock 是标准库的一个类, 在 JVM 外实现的(基于 Java 实现).
②synchronized 使用时不需要手动释放锁;ReentrantLock 使用时需要手动释放,使用起来更灵活, 但是也容易遗漏 unlock.
③synchronized 在申请锁失败时, 会死等;ReentrantLock 可以通过 trylock 的方式等待一段时间就放弃.
④synchronized 是非公平锁, ReentrantLock 默认是非公平锁. 可以通过构造方法传入一个 true 开启公平锁模式.
//ReentrantLock构造方法传入一个true
public ReentrantLock(boolean fair){
sync=fair?new FairSync():new NonfairSync();
}
⑤更强大的唤醒机制. synchronized 是通过 Object 的 wait / notify 实现等待-唤醒. 每次唤醒的是一个随机等待的线程. ReentrantLock 搭配 Condition 类实现等待-唤醒, 可以更精确控制唤醒某个指定的线程.
三、如何选用synchronized 和 ReentrantLock
①锁竞争不激烈的时候, 使用 synchronized, 效率更高, 自动释放更方便.
②锁竞争激烈的时候, 使用 ReentrantLock, 搭配 trylock 更灵活控制加锁的行为, 而不是死等.
③如果需要使用公平锁, 使用 ReentrantLock.