ReentrantLock实现了Lock接口,加锁和解锁都需要显式写出,注意一定要在适当时候unlock
和synchronized相比,ReentrantLock用起来会复杂一些。在基本的加锁和解锁上,两者是一样的,所以无特殊情况下,推荐使用synchronized。ReentrantLock的优势在于它更灵活、更强大,增加了轮训、超时、中断等高级功能
ReentrantLock的内部类Sync继承了AQS,分为公平锁FairSync和非公平锁NonfairSync。
公平锁:线程获取锁的顺序和调用lock的顺序一样,FIFO;
非公平锁:线程获取锁的顺序和调用lock的顺序无关,全凭运气。
ReentrantLock默认使用非公平锁是基于性能考虑,公平锁为了保证线程规规矩矩地排队,需要增加阻塞和唤醒的时间开销。如果直接插队获取非公平锁,跳过了对队列的处理,速度会更快
公平锁:
首先判断当前AQS的state是否等于0,锁是否被占用,如果没有被占用的话,继续判断队列中是否有排在前面的线程在等待锁,没有的话就修改statte状态
然后将当前线程记录为独占锁的线程,继续判断当前线程是否为独断锁的线程,ReentrantLock是可冲入的,线程可以不停地Lock来增加state的值,对应的需要unlock来解锁,减少state的值
如果上面的条件判断失败,即获取锁失败,则将线程加入到等待线程队列队尾,然后阻塞线程,等待被唤醒
当调用unlock后,会唤醒等待队列中的头节点的下一个节点,被唤醒的线程重新请求获取锁,
非公平锁:
非公平锁逻辑基本跟公平锁一致,最本质的区别是,当当前的锁状态没有被占用时,当前线程
可以直接占用,而不需要判断当前队列中是否有等待线程,
网友评论