Lock和synchronized的区别
- 在java中,Lock为一个接口,而synchronized为内置的关键字。
- Lock接口中的tryLock()方法可以去尝试获取线程的锁,而synchronize必须等到另一个线程执行完毕后释放了锁后才可以拿到锁。
public class Test{
// 实例化Lock接口对象
Lock lock = ...;
// 尝试获取锁
if(lock.tryLock()){
try{
// 处理事务
}finally{
// 释放锁
lock.unlock();
}
}else{
// 未获得到锁所需要的操作
}
}
注:分为有参和无参的tryLock() 方法
1. boolean tryLock();
2. boolean tryLock(long time, TimeUnit unit) throws InterruptedException;
该方法限定了一个尝试获取锁的时间
关于更多详细的tryLock()方法:https://blog.csdn.net/qq_43323776/article/details/82939005
-
Lock 需要手动释放锁,而synchronized则会自动释放锁。
synchronized 在线程执行完同步代码或者线程执行过程中发生异常会释放锁;
而使用Lock,即使线程在执行过程中发生异常也不会释放锁,所以必须手动在finally中使用unlock()方法释放锁,否则会造成线程死锁
-
同步块或同步方法只能覆盖一个方法,
而我们可以在一个方法里获取锁,然后使用lock API在另一个方法中释放锁。
-
synchronized关键字实现的是非公平锁,而Lock的实现类ReentrantLock可以实现公平锁。
// 参数可为空,默认为false,当为true表示实现公平锁 Lock lock = new ReentrantLock(boolean fair);
公平锁是指当锁可用时,在锁上等待时间最长的线程将获得锁的使用权 。
-
通过Lock可以创建多个Condition对象,然后可以通过不同的线程多不同的condition对象进行await()释放锁,进入等待阻塞。
注:await()是ConditionObject类中的方法,而ConditionObject实现了Condition接口;而ReentrantLock里面默认有实现newCondition()方法,新建一个条件对象 。
Lock lock = new ReentrantLock();
// 创建条件对象
Condition condition = lock.newCondition();
参考官网:https://www.journaldev.com/2377/java-lock-example-reentrantlock