ReentrantLock默认实现是非公平,除非指定公平为true
Lock lock = new ReentrantLock(true);
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock() {
sync = new NonfairSync();
}
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
一、公平锁
是指多个线程按照申请锁的顺序来获取锁,类似于排队,先来后到。
讲究先来后到,线程在获取锁的时候,如果这个锁的等待队列中已经有线程在等待了,那么当前线程就会进入等待队列中。
二、非公平锁
是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁,在高并发的情况下,有可能会造成优先级反转或者饥饿现象。
优点:吞吐量比公平锁大
对于 synchronized 而言,也是非公平的
三、Synchronized 和 lock 有什么区别
之前是在synchronized中使用唤醒和等待,现在JUC包中的lock也可以使用唤醒和等待。
1、原始构成
synchronized是关键字属于JVM层面
底层由monitorenter、monitorexit实现(通过monitor对象完成,其实wait/notify等方法也依赖monitor对象,所以只有在同步块或方法中才能调用wait/nofity等方法)
Lock是具体类(JUC包下的)是API层面的
2、使用方法
- synchronized:不需要手动去释放锁,当synchronized代码执行完后系统会自动让线程释放锁的占用
ReentrantLock:需要用户去手动释放锁,若没有主动释放锁,就有可能导致死锁。
3、等待是否可中断
synchronized:不可中断,除非抛出异常或正常运行完成。
ReentrantLock:可中断,1、设置超时方法,trylock(timeout,timeunit unit)2、LockInterruptibly()放代码块中,调用interrupt()方法可中断。
4、是否公平
synchronized:非公平锁
ReentrantLock:可公平、可不公平,默认非公平,构造方法传入true则变成公平
5、锁绑定多个条件Condition
synchronized:没有
- ReentrantLock:用来实现分组唤醒需要唤醒的线程,可以精确唤醒,而不是像synchronized那样要么随机唤醒,要么唤醒全部线程