ReentrantLock有以下几个特性。基本的获取锁操作,基本的释放锁操作,可轮询的锁获取操作,可中断的获取锁操作,定时获取锁操作,使用公平队列。
首先ReentrantLock的实现主要是依赖于 AbstractQueuedSynchronizer。AbstractQueuedSynchronizer它维护一个状态信息单一的整数 state。state在此用来表示拥有锁的线程请求获取锁的次数。 state==0表示锁为可获取状态。
基本的获取锁操作:lock()方法:
public void lock() {
sync.lock();
}
sync为ReentrantLock静态内部类Sync的一个引用。
无参数的构造函数默认sync指向一个NonfairSync().(不公平队列)。Sync扩展了AbstractQueuedSynchronizer.而NonfairSync扩展了Sync.
NonfairSync中lock()方法的实现如下:
- final void lock() {
- if (compareAndSetState(0, 1))//AbstractQueuedSynchronizer的方法(原子操作),如果当前的state的值为0则把state的值设为1
- setExclusiveOwnerThread(Thread.currentThread());//设置当前锁的有占有者为当前线程
- else
- acquire(1);//如果是拥有锁的线程请求state++,否则当前线程阻塞,并且把线程存储到阻塞队列中。(AbstractQueuedSynchronizer中使用链表来维护的线程阻塞队列)
- }
final void lock() { if (compareAndSetState(0, 1))//AbstractQueuedSynchronizer的方法(原子操作),如果当前的state的值为0则把state的值设为1 setExclusiveOwnerThread(Thread.currentThread());//设置当前锁的有占有者为当前线程 else acquire(1);//如果是拥有锁的线程请求state++,否则当前线程阻塞,并且把线程存储到阻塞队列中。(AbstractQueuedSynchronizer中使用链表来维护的线程阻塞队列) }
可轮询的锁获取操作:具体的实现为:
- final boolean nonfairTryAcquire(int acquires) { //此处acquirs为1
- final Thread current = Thread.currentThread();
- int c = getState();
- if (c == 0) { //如果state为0证明锁可获取
- if (compareAndSetState(0, acquires)) { //原子操作,如果当前的state为0,则把state的值设置为1.
- setExclusiveOwnerThread(current);//设置当前锁的占有者为当前线程
- return true;
- }
- }
- else if (current == getExclusiveOwnerThread()) { //如果当前锁的占有者为当前线程
- int nextc = c + acquires;
- if (nextc < 0) // overflow
- throw new Error("Maximum lock count exceeded");
- setState(nextc);//设置state为占有锁线程请求锁的次数
- return true;
- }
- return false;
- }