1. 概念介绍
1.1 线程平安锁
Synchronize(同步锁)和 ReentrantLock(可重入锁)都是 Java 中的罕用锁,都是用来保障线程平安的。
两者都是同步锁,且都是阻塞同步。
-
阻塞同步:当一个线程获取锁后,其余线程只能期待(进入阻塞态),期待获取锁的线程开释锁后,其余线程能力获取锁。
1.2 偏心锁
在多个线程申请资源的时候,如果依据线程申请的程序来分配资源,那么这个锁就是 偏心锁,反之就是非偏心锁。
1.3 响应中断 / 期待可中断
在线程阻塞期间,阻塞线程期待资源的应用,如果这种期待状态可能被中断,从而开释线程去做其余的事件,这就称为 期待可中断。
2. 区别
2.1 底层实现
Synchronize 是 Java 的关键字,ReentrantLock 是 Java 类。因而,Synchronize 是 JVM 层面语法层面的同步锁,ReentrantLock 是 API 层面的同步锁
2.2 锁的用法
- 设置锁和开释锁:Synchroinze 是主动加锁和开释锁的,ReentrantLock 设置和开释都须要手动操作;
- 润饰的对象:Synchroinze 能够润饰办法和代码块,ReentrantLock 只能润饰代码块
如下代码展现了它们的具体用法:
-
Synchronize 作为关键字润饰办法或者代码块即可;
//synchronized 润饰一个办法时,这个办法叫同步办法。public synchronized void test() {// 办法体 ``} synchronized(Object){ // 括号中示意须要锁的对象. // 线程执行的时候会对 Object 上锁 }
-
ReentrantLock 的应用须要先创立锁对象,而后在须要加锁的代码块中调用 lock()办法加锁,应用结束后调用 unlock()办法开释锁。
public class LockExample { // 创立锁对象 private final ReentrantLock lock = new ReentrantLock(); public void method() { // 加锁操作 lock.lock(); try {// ...} finally { // 开释锁 lock.unlock();} } }
2.3 锁的特点
ReentrantLock 相比于 Synchronize,有以下特点:
- 响应中断:ReentrantLock 能够响应中断,也就是在其余线程阻塞期间,能够在长时间无奈获取响应的状况下,自行中断期待状态
- 偏心锁:ReentrantLock 默认是不偏心锁,然而能够设置为偏心锁,也就是能够依据线程申请的程序来分配资源
- 绑定多个条件:一个 ReentrantLock 能够同时绑定多个条件,而一个 Synchronize 锁只能绑定一个条件。
这些特点都是 Synchronize 锁所不具备的。
2.4 性能比拟
Sychronize 是 JVM 层面的同步锁,实现简略,性能较好;
ReentrantLock 是 API 层面的同步锁,须要手动创立和开释锁,性能较差,然而减少了很多特点,灵活性较好。
2.5 实用场景
Synchronize 实用于:
- 简略的同步场景;
- 对同步性能有较高要求
- 不须要响应中断、偏心锁、绑定多个条件;
ReentrantLock 实用于:
- 需要更简单的同步场景
- 对性能要求较低
- 须要响应中断、偏心锁、绑定多个条件;
3. 总结比拟
对上述内容进行总结,如下表所示:
参考文献
- Synchronize 和 ReentrantLock 区别
- 面试突击:synchronized 和 ReentrantLock 有什么区别?
- Java 中 synchronized 和 ReentrantLock 的区别