可重入锁、公平锁、非公平锁、互斥锁独占锁排他锁、共享锁源码分析

it2023-01-21  55

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

 

最新回复(0)