ReentrantLock:
内部有三个final的静态内部类,其中Sync继承了AbstractQueuedSynchronizer(AQS),NonfairSync和FairSync则继承了Sync
-
和synchronized都属于<可重入锁>, 可重入锁代表, 在一个线程获取锁之后,该线程对该锁的其他后续操作都可以直接获得锁.
-
非公平锁 无参构造函数默认为非公平锁, 线程在竞争锁时,采取先到先得的方式
-
公平锁: 线程在竞争锁时,会以队列的形式进行排队
值得注意的是,非公平锁和公平锁,都能保证队列中排在前面的线程比排在后面的先获取锁,但非公平锁中,队列外的线程有可能比队列内的线程先获取到锁,这就提现了非公平性.
非公平锁lock()方法:
-
尝试CAS设置state的值
若设置成功
-
将该线程设置为该锁的占用线程
若没有成功
-
则调用AQS的acquire(1)方法
-
acquire(1)方法的第一个判断条件是 !tryAcquire(arg) 方法,arg就是acquire(1)的参数
-
非公平锁对tryAcquire()方法的实现为:首先获取当前线程和当前锁的state值,若state值为0,代表该锁目前没有线程占用,则再次使用CAS去设置state,若设置成功,则将该线程设为该锁的占用线程,返回true.设置不成功,返回false.若state的值不为0并且当前线程是该锁的占用线程,将state值设为state+1,返回true.其他情况返回false,接着调用addWaiter(Node mode)方法,将线程加入等待队列,并调用 acquireQueued(),尝试让队列中的第一个Node中的线程去获取锁,获取成功,当前线程阻塞,lock()方法结束.
公平锁lock()方法:
-
直接调用AQS的acquire(1)方法
-
公平锁对tryAcquire()方法的实现为:首先获取当前线程和当前锁的state值,若state值为0,先调用hasQueuedPredecessors()方法判断队列中是否有等待的线程,如果有,则返回false,如果没有等待线程,则尝试使用CAS去设置state的值,若设置成功,则将该线程设为该锁的占用线程,返回true.设置不成功,返回false.若state的值不为0并且当前线程是该锁的占用线程,将state值设为state+1,返回true.其他情况返回false,接着调用addWaiter(Node mode)方法,将线程加入等待队列,并调用 acquireQueued(),尝试让队列中的第一个Node中的线程去获取锁,获取成功,当前线程阻塞,lock()方法结束.