公平锁与非公平锁
大多数情况下,锁的申请都是非公的,当线程1与线程2都在请求锁A,当锁A可用时,系统只会从阻塞队列中随机选择一个线程,不能保证其公平性。
非公平锁,系统会倾向于让一个线程再次获得已经持有的锁,这种分配策略是高效的但非公平
公平锁会按照时间先后顺序保证先到先得,公平锁的这一特点不会让线程饥饿(排队的多了,可能调度器一直没有选中你),看起来很公平,但是要实现公平锁,必须要求系统维护一个有序队列,因此实现成本高,性能低,因此默认情况下默认锁是非公平,不是特别的需求,一般不使用公平锁
多个线程不会发生同一个线程连续多次获得锁的可能,保证了锁的公平性
synchronized内部锁就是非公平的。ReentrantLock重入(具有可重入性)锁提供了一个构造方法,有参为公平锁,无参为非公平锁
ReentrantLock(Boolean fair);当创建锁对象时,实参传递true可以将该锁设置为公平锁
ReentrantLock lock = new ReentrantLock(); //非公平
ReentrantLock lock = new ReentrantLock(true); //公平
lock.lock();//获得锁
lock.unlock();//释放锁
lock.lockInterruptibly();//如果当前线程未被中断则获得锁, 如果当前线程被中断则出现异常
lock.tryLock(long time, TimeUnit unit);//在给定等待时长内锁没有 被另外的线程持有,并且当前线程也没有被中断,则获得该锁.通过该 方法可以实现锁对象的限时等待.
Condition condition = lock.newCondition();//使用 Condition 类可以进行选择性通知.
condition .await()用于等待
condition .signal()用于唤醒一个等待的线程 signalAll() 用于唤醒所有等待的线程
int getHoldCount();//返回当前线程调用lock()方法的次数