Lock是一个接口,通常会用ReentrantLock(可重入锁)来实现这个接口。
独占式获取锁
1.lock()
ReentrantLock lock=new ReentrantLock();
lock.lock();
当获取锁时通常会调用ReentrantLock的lock()方法。而lock()方法在ReentrantLock是一个抽象方法,默认情况下ReentrantLock是一个非公平锁,
lock()方法具体实现在ReentrantLock的静态内部类NonfairSync中,源码如下:
public class ReentrantLock implements Lock, java.io.Serializable {
abstract static class Sync extends AbstractQueuedSynchronizer {
abstract void lock();
}
static final class NonfairSync extends Sync {
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
}
这里的lock()方法先通过CAS将state的值从0变为1(ReentrantLock用state表示“持有锁的线程已经重复获取该锁的次数”):当state实际值等于预期值0时,表示当前没有线程持有该锁,更新state值为1,将ExclusiveOwnerThread的值为当前线程(Exclusive是独占的意思,ReentrantLock用exclusiveOwnerThread表示“持有锁的线程”),那么该线程获取锁成功。如果CAS失败。说明state实际值并不是0,也就是说已经有线程持有该锁,此时执行acquire(1)再次请求锁。
2.acquire()
调用acquire():会调用ReentrantLock的静态内部AbstractQueuedSynchronizer的acquire方法()。看源码:
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
/**
* Acquires in exclusive mode, ignoring interrupts. Implemented
* by invoking at least once {@link #tryAcquire},
* returning on success. Otherwise the thread is queued, possibly
* repeatedly blocking and unblocking, invoking {@link
* #tryAcquire} until success. This method can be used
* to implement method {@link Lock#lock}.
*
* @param arg the acquire argument. This value is conveyed to
* {@link #tryAcquire} but is otherwise uninterpreted and
* can represent anything you like.
*/
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
}
从注释我们可以了解到acqiure的作用:我理解的是acquire请求独占锁,忽略所有中断,至少执行一次tryAcquire,如果tryAcquire()再次获取锁成功就直接退出,否则线程进入阻塞- - -唤醒2种状态切换中,直到tryAcquire成功。
可以看到if语句是&&,那么先看tryAcquire()方法。
注:以下方法没有特殊表明都在静态内部类AQS中。
3.tryAcquire()
acquire失败后再次用tryAcquire()获取同步状态。
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (compareAndSetState(0, acquires)) {
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);
return true;
}
return false;
}
nonfairTryAcquire()再次获取锁,先判断state是否为0,如果为0即没有线程获取该锁,通过CAS该线程获取到锁。如果state不为0,判断当前线程是否是getExclusiveOwnerThread即持有锁线程,是的话,就将state++,也就是可重入的体现。否则再次获取同步状态失败。
当state=0通过CAS保证同步,即同一个时刻只有一个线程可以获取到锁,但是如果当前线程是持有锁线程并没有保证同步是因