今天简单的分析一下ReentrantLock的源码,碍于水平有限,如有疏漏或者错误之处请指正。
ReentrantLock重入性、公平性:http://ifeve.com/reentrantlock-and-fairness/
JDK版本:jdk1.8.0_121
切入正题:
当我们使用它的时候一般都是这样new对象的:
// 默认是非公平锁
Lock lock = new ReentrantLock();
那么先看一下ReentrantLock的构造函数。
public ReentrantLock() {
//当没有参数的时候,默认创建的是非公平锁。
sync = new NonfairSync();
}
//当指定 fair这个是否公平参数时进行相应的创建。
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
以上代码中出现了一个sync和两个new FairSync() ; new NonfairSync();对象,那么他们又分别是什么呢?
private final Sync sync;//它是ReentrantLock的私有对象引用
/*
*而Sync则是ReentrantLock内部的抽象类,它继承自*AbstractQueuedSynchronizer
*/
abstract static class Sync extends AbstractQueuedSynchronizer {
abstract void lock();
....其他的不一一列举
}
关于AbstractQueuedSynchronizer队列同步器,推荐文章:http://www.jianshu.com/p/ac0fb814e1a3
而NonfairSync 和FairSync 则都是继承自上述抽象类Sync,他们同样是ReentrantLock的内部类
static final class NonfairSync extends Sync {
}
static final class FairSync extends Sync {
}
Synchorized区别
- 都具备可重入性
- 锁的实现 显示锁基于JDK实现 synchorized是jvm层面
- 性能区别 jdk6以后性能已经不存在太大差距,推荐使用Synchorized,因为jvm更容易获得使用状况并针对做出优化
- 使用上,Synchorized无需格外关注,ReentrantLock则需要开发者在finally中释放锁,否则异常会造成锁无法释放
- 都是悲观策略的实现,互斥同步即阻塞同步
ReentrantLock独有的功能
- 可以指定是否公平锁,通过构造即可实现,但是公平锁会使性能降低,吞吐量下降
- 提供了Condition类,可以实现多条件唤醒需要唤醒的线程
- 提供中断等待锁的线程机制 lock.lockInterruptibly()