一、简介
在JDK1.5后,有Doug Lea编写的concurrent包提供;我们经常拿ReentrantLock和synchronized对比,都是互斥锁,可以保证线程安全,但是ReentrantLock具有比synchronized更多的特性,比如支持手动加解锁,实现公平与非公平锁;
二、加解锁大致流程
先看看ReentrantLock主要属性,主要是AQS框架中提供的state(锁状态,0代表无锁,大于零代表有线程获取到了锁),head队头,tail队尾;
1、加锁时,先使用CAS试着获取锁(state + 1),获取到锁,把持有锁的线程设置为当前线程,则继续执行
2、如果获取锁失败,则会把线程对象放入AQS双向队列
3、当获取锁的线程执行完成后,则释放锁(state-1),把持有锁的线程设置为空,从队列中获取头部节点,唤醒线程,继续执行
三、源码分析
构造方法从构造方法看的出来,如果直接new,则使用的是非公平锁,传入boolean类型,true时为公平锁,我们从公平锁来看加锁流程
公平锁lock方法 acquire方法 tryAcquire CAS方法使用CAS获取锁,使用unsafe类,传入当前对象,使用state的偏移量来执行CAS操作,该操作是原子的;当获取锁成功时,则跳出lock方法,继续执行该线程;当获取锁失败时,我们继续到acquire方法,进行入队操作;
acqireQueued 设置节点状态 挂起线程方法到此进入lock方法,线程被挂起,等待获取到锁的线程释放锁后来唤醒该线程;我们再来继续看下nulock方法
unlock release方法 tryRelease unparkSuccessor
网友评论