可重入锁:获取锁后再次请求获取同一把锁,不再抢占锁,而是只增加获得锁的次数。
synchronized、ReentrantLock是可重入锁。
公平锁:按照线程抢占锁的顺序使线程获得锁。
非公平锁:不按照线程抢占锁的顺序使线程获得锁。线程是否能抢占锁和线程抢占锁的顺序无关,随机抢占。
ReentrantLock默认是非公平锁。
/**
* Creates an instance of {@code ReentrantLock}.
* This is equivalent to using {@code ReentrantLock(false)}.
*/
public ReentrantLock() {
sync = new NonfairSync();
}
/**
* Creates an instance of {@code ReentrantLock} with the
* given fairness policy.
*
* @param fair {@code true} if this lock should use a fair ordering policy
*/
public ReentrantLock(boolean fair) {
sync = fair ? new FairSync() : new NonfairSync();
}
互斥锁(也称独占锁、排他锁):多个线程不能获取同一把锁,如同步锁synchronized。
共享锁:多个线程可以获取同一把锁,如读写锁ReadWriteLock的读锁,读和读不互斥。读写锁的读和写互斥,写和写互斥。
AbstractQueuedSynchronizer.Node:
/** Marker to indicate a node is waiting in shared mode */
static final Node SHARED = new Node();
/** Marker to indicate a node is waiting in exclusive mode */
static final Node EXCLUSIVE = null;
跟踪一下lock()源码:
ReentrantLock:
public void lock() {
sync.acquire(1);
}
NonfairSync:
final void lock() {
if (compareAndSetState(0, 1))
setExclusiveOwnerThread(Thread.currentThread());
else
acquire(1);
}
FairSync:
final void lock() {
acquire(1);
}
AQS:AbstractQueuedSynchronizer:
public final void acquire(int arg) {
// tryAcquire(arg) 尝试获取锁是否成功
// addWaiter(node)加入等待获取锁的队列
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
NonfairSync:
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
Sync:
final boolean nonfairTryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState(); // private volatile int state;
if (c == 0) {
// 抢占锁,获取锁成功
if (compareAndSetState(0, acquires)) { // unsafe.compareAndSwapInt(this, stateOffset, expect, update);
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
// 重入锁,线程获取次数+1,获取锁成功
int nextc = c + acquires;
if (nextc < 0) // 重入次数不能超过int最大值
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}
FairSync:
protected final boolean tryAcquire(int acquires) {
final Thread current = Thread.currentThread();
int c = getState();
if (c == 0) {
if (!hasQueuedPredecessors() && compareAndSetState(0, acquires)) { // 没有队列前驱才能获取到锁,保证按照抢占顺序获取锁,保证公平
setExclusiveOwnerThread(current);
return true;
}
}
else if (current == getExclusiveOwnerThread()) {
int nextc = c + acquires;
if (nextc < 0)
throw new Error("Maximum lock count exceeded");
setState(nextc);
return true;
}
return false;
}