lock的实现类是ReentrantLock。lock用的是Sync下面的lock锁。
public void lock() {
sync.lock();
}
sync里面有内部抽象类的公平和非公平的内部类
我们用的Lock默认的是非公平锁
public ReentrantLock() {
sync = new NonfairSync();
}
非公平锁的lock方法用的是cas比较并交换
static final class NonfairSync extends Sync {
private static final long serialVersionUID = 7316153563782823691L;
/**
* Performs lock. Try immediate barge, backing up to normal
* acquire on failure.
*/
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
compareAndSetState 是个CAS比较并交换的方法,如果是0,可以获得锁。
compareAndSetState的源码:
protected final boolean compareAndSetState(int expect, int update) {
// See below for intrinsics setup to support this
return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
}
如果是1则进入else acquire
acquire的源码是这个
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
尝试获得锁失败同时显示的是等待标记,就终端该线程。
CAS的特点:
1、循环开销很大!
2、内存操作,每次只能保证一个共享变量的原子性!
3、出现ABA 问题?数据库中用version来解决。