独占锁 :同一时间内只有一个线程可以获取这个锁并占用资源。其他线程想要获取锁,必须等待这个线程释放锁。
公平锁
先从lock方法中去获取锁,进入acquire()方法 ,先 tryAcquire()去尝试获取锁
如果没有获取成功 就封装成节点 进入CLH队列等待
static final class FairSync extends Sync {
final void lock() {
acquire(1);
}
// AbstractQueuedSynchronizer.acquire(int arg)
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {//当前锁的状态是否为0
// 1. 和非公平锁相比,这里多了一个判断:是否有线程在等待 ,无线程等待就使用CAS修改同步状态
if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) {
setExclusiveOwnerThread(current)
return true;
}
}//当前锁的状态不为0,所以已经被占有,则判断当前线程是否已经Owner占有该锁; 是则重入 否则失败
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
非公平锁
static final class NonfairSync extends Sync {
final void lock() {
// 2. 和公平锁相比,这里会直接先进行一次CAS,成功就返回了
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
// AbstractQueuedSynchronizer.acquire(int arg)
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
//3.这里也是直接CAS,没有判断前面是否还有节点。
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;
}
-
非公平锁进入lock方法后,会直接先进行一次CAS获取锁,如果没有获取到再进入acquire方法去获取。
-
这个acquire()方法基于AQS。先tryAcquire()去尝试获取锁,如果没有获取成功,就在CLH队列中增加一个当前线程的节点,表示等待抢占