可重入锁:获取锁后再次请求获取同一把锁,不再抢占锁,而是只增加获得锁的次数。 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; }