🎈专栏链接:多线程相关知识详解
synchronized和ReentrantLock的 区别 = 缺点 + 优势
synchronized和ReentrantLock两者都是可重入锁
ReentrantLock的三个核心方法:
Ⅰ.lock(加锁)
Ⅱ.unlock(解锁)
Ⅲ.tryLock(尝试加锁)
import java.util.concurrent.locks.ReentrantLock;
public class Demo1 {
public static void main(String[] args) {
ReentrantLock locker = new ReentrantLock();
//加锁
locker.lock();
//....
//解锁
locker.unlock();
}
}
如果在ReentrantLock的加锁解锁中间发生了异常就有可能导致后面的解锁操作无法执行到(ReentrantLock的缺点),而使用synchronized就不用担心这个问题,因为只要出了代码块就一定执行解锁操作
虽然ReentrantLock有缺点,但是它有一些特定的功能是synchronized做不到的
ReentrantLock的3个优点:
1.tryLock 试试看能不能加上锁,试成功了,就加锁成功,试失败了,就放弃加锁,并且还可以指定加锁的等待超时时间(在开发过程中,"死等的策略"需要特别注意,tryLock就提供了应对的方法)
2.ReentrantLock 可以实现公平锁,它默认是非公平的,在构造的时候给它传入一个参数true就变公平锁了
ReentrantLock locker = new ReentrantLock(true);
3.synchronized搭配的是 wait/notify 来实现等待通知机制的,唤醒操作是随机唤醒一个等待的线程
ReentrantLock 搭配的是 Condition类 实现的,唤醒操作是可以指定唤醒哪个等待通知的线程的
synchronized是java的关键字,底层是基于JVM实现的(通过C++实现的),而ReentrantLock是标准库中的一个类,底层是基于Java实现的