ReentrantLock
可重入互斥锁,和synchronized的定位类似,都用于实现互斥效果,保证线程安全。
ReentrantLock的用法:
- lock():加锁,获取不到锁就死等
- trylock():超时时间加锁
如果设置了超时参数,超时后放弃加锁
如果不设置超时参数,不会导致阻塞,加锁成功返回true,失败返回false - unlock():解锁
ReentrantLock lock = new ReentrantLock(); -------------------------------------------------- lock.lock(); try { //working } finally { lock.unlock(); }ReentrantLock和synchronized的区别
- synchronized是一个关键字,是JVM内部实现的(大概率是基于C++实现)
ReentrantLock是标准库的一个类,在JVM外实现的(基于Java实现) - synchronized使用代码块进行加锁解锁,不需要考虑解锁问题
ReentrantLock需要lock/unlock方法,使用灵活,但是容易遗漏unlock - synchronized在申请锁失败后会死等
ReentrantLock可以使用trylock方法等待一段时间后就放弃 - synchronized是非公平锁
ReentrantLock默认是非公平锁,但是可以通过构造方法传入一个true开启公平锁模式 - synchronized使用Object类的wait/notify实现等待/唤醒,每次唤醒都是随机唤醒
ReentrantLock可以搭配Condition类实现等待/唤醒,可以更精准得唤醒某个指定的线程。
- 竞争不激烈的时候使用synchronized锁,效率更高,自行解锁更方便
- 锁竞争激烈的时候使用ReentrantLock锁,搭配trylock方法更灵活得控制加锁,而不是死等
- 如果要使用公平锁,使用ReentrantLock锁