//先拿ReentrantLock分析看看 public class ReentrantLock implements Lock, java.io.Serializable { private static final long serialVersionUID = 7373984872572414699L; /** Synchronizer providing all implementation mechanics */ private final Sync sync;//獲取鎖,和釋放鎖,都是變量操做 /** * Base of synchronization control for this lock. Subclassed * into fair and nonfair versions below. Uses AQS state to * represent the number of holds on the lock. Sync 繼承自AbstractQueuedSynchronizer(所謂AQS) * 這個Sync是個抽象類,下面公平鎖FairSync和非公平鎖NonfairSync會實現它 */ abstract static class Sync extends AbstractQueuedSynchronizer { private static final long serialVersionUID = -5179523762034025860L; /** * Performs {@link Lock#lock}. The main reason for subclassing * is to allow fast path for nonfair version. */ abstract void lock();//等着公平鎖和非公平鎖的實現 /** * Performs non-fair tryLock. tryAcquire is * implemented in subclasses, but both need nonfair * try for trylock method.嘗試獲取鎖 */ final boolean nonfairTryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState();//是它,就是它,來獲取【依賴狀態變量】,鎖的根基變量 if (c == 0) { if (compareAndSetState(0, acquires)) {//是它,就是它,經過cas原則更新【依賴狀態變量】,鎖的根基方法,更新成功了,可理解是獲取鎖成功,更新失敗了,就算獲取鎖失敗(jdk裏本沒有鎖) 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; } //釋放鎖 protected final boolean tryRelease(int releases) { int c = getState() - releases;//減小 狀態變量值 if (Thread.currentThread() != getExclusiveOwnerThread())//當前線程是鎖的擁有者線程嗎? throw new IllegalMonitorStateException(); boolean free = false; if (c == 0) {//若是沒有線程擁有鎖,就設置null free = true; setExclusiveOwnerThread(null); } setState(c); return free; } //是否被當前線程擁有 protected final boolean isHeldExclusively() { // While we must in general read state before owner, // we don't need to do so to check if current thread is owner return getExclusiveOwnerThread() == Thread.currentThread(); } //題外話:顯示鎖,多等待隊列實現(其實就是new 個新對象,歸根結底,仍是一個對象,一個條件隊列) final ConditionObject newCondition() { return new ConditionObject(); } // Methods relayed from outer class final Thread getOwner() { return getState() == 0 ? null : getExclusiveOwnerThread(); } final int getHoldCount() { return isHeldExclusively() ? getState() : 0; } final boolean isLocked() { return getState() != 0; } /** * 從一個輸入流重構鎖。這個怎麼玩的炫? * Reconstitutes this lock instance from a stream. * @param s the stream */ private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { s.defaultReadObject(); setState(0); // reset to unlocked state } } /** * Sync object for non-fair locks * 非公平鎖的實現 */ 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() {//調的仍是AQS裏的方法,因此說AQS是根基類 if (compareAndSetState(0, 1)) setExclusiveOwnerThread(Thread.currentThread()); else acquire(1);//這個方法是AQS裏的方法,但它又回調子類tryAcquire(int arg)方法,也就是下面的tryAcquire方法,也就是模板方法模式,AQS負責流程調度,具體每一個鎖的獲取,失敗語義,本身定義。 } protected final boolean tryAcquire(int acquires) { return nonfairTryAcquire(acquires); } } /** * Sync object for fair locks * 公平鎖,(弄個隊列FIFO) */ static final class FairSync extends Sync { private static final long serialVersionUID = -3000897897090466540L; final void lock() { acquire(1); } /** * Fair version of tryAcquire. Don't grant access unless * recursive call or no waiters or is first. */ protected final boolean tryAcquire(int acquires) { final Thread current = Thread.currentThread(); int c = getState(); if (c == 0) { if (!hasQueuedPredecessors() &&//沒有在前面等待的線程,(體現公平性),而且compareAndSetState 成功,就獲取鎖成功了。 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; } } /** * 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(); } /** * Acquires the lock. * * <p>Acquires the lock if it is not held by another thread and returns * immediately, setting the lock hold count to one. * * <p>If the current thread already holds the lock then the hold * count is incremented by one and the method returns immediately. * * <p>If the lock is held by another thread then the * current thread becomes disabled for thread scheduling * purposes and lies dormant until the lock has been acquired, * at which time the lock hold count is set to one. */ public void lock() { sync.lock(); } /** * Acquires the lock unless the current thread is * {@linkplain Thread#interrupt interrupted}. * * <p>Acquires the lock if it is not held by another thread and returns * immediately, setting the lock hold count to one. * * <p>If the current thread already holds this lock then the hold count * is incremented by one and the method returns immediately. * * <p>If the lock is held by another thread then the * current thread becomes disabled for thread scheduling * purposes and lies dormant until one of two things happens: * * <ul> * * <li>The lock is acquired by the current thread; or * * <li>Some other thread {@linkplain Thread#interrupt interrupts} the * current thread. * * </ul> * * <p>If the lock is acquired by the current thread then the lock hold * count is set to one. * * <p>If the current thread: * * <ul> * * <li>has its interrupted status set on entry to this method; or * * <li>is {@linkplain Thread#interrupt interrupted} while acquiring * the lock, * * </ul> * * then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. * * <p>In this implementation, as this method is an explicit * interruption point, preference is given to responding to the * interrupt over normal or reentrant acquisition of the lock. * * @throws InterruptedException if the current thread is interrupted */ public void lockInterruptibly() throws InterruptedException { sync.acquireInterruptibly(1); } /** * Acquires the lock only if it is not held by another thread at the time * of invocation. * * <p>Acquires the lock if it is not held by another thread and * returns immediately with the value {@code true}, setting the * lock hold count to one. Even when this lock has been set to use a * fair ordering policy, a call to {@code tryLock()} <em>will</em> * immediately acquire the lock if it is available, whether or not * other threads are currently waiting for the lock. * This "barging" behavior can be useful in certain * circumstances, even though it breaks fairness. If you want to honor * the fairness setting for this lock, then use * {@link #tryLock(long, TimeUnit) tryLock(0, TimeUnit.SECONDS) } * which is almost equivalent (it also detects interruption). * * <p> If the current thread already holds this lock then the hold * count is incremented by one and the method returns {@code true}. * * <p>If the lock is held by another thread then this method will return * immediately with the value {@code false}. * * @return {@code true} if the lock was free and was acquired by the * current thread, or the lock was already held by the current * thread; and {@code false} otherwise * 經過sync獲取鎖,默認是非公平的。 */ public boolean tryLock() { return sync.nonfairTryAcquire(1); } /** * Acquires the lock if it is not held by another thread within the given * waiting time and the current thread has not been * {@linkplain Thread#interrupt interrupted}. * * <p>Acquires the lock if it is not held by another thread and returns * immediately with the value {@code true}, setting the lock hold count * to one. If this lock has been set to use a fair ordering policy then * an available lock <em>will not</em> be acquired if any other threads * are waiting for the lock. This is in contrast to the {@link #tryLock()} * method. If you want a timed {@code tryLock} that does permit barging on * a fair lock then combine the timed and un-timed forms together: * * <pre>if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... } * </pre> * * <p>If the current thread * already holds this lock then the hold count is incremented by one and * the method returns {@code true}. * * <p>If the lock is held by another thread then the * current thread becomes disabled for thread scheduling * purposes and lies dormant until one of three things happens: * * <ul> * * <li>The lock is acquired by the current thread; or * * <li>Some other thread {@linkplain Thread#interrupt interrupts} * the current thread; or * * <li>The specified waiting time elapses * * </ul> * * <p>If the lock is acquired then the value {@code true} is returned and * the lock hold count is set to one. * * <p>If the current thread: * * <ul> * * <li>has its interrupted status set on entry to this method; or * * <li>is {@linkplain Thread#interrupt interrupted} while * acquiring the lock, * * </ul> * then {@link InterruptedException} is thrown and the current thread's * interrupted status is cleared. * * <p>If the specified waiting time elapses then the value {@code false} * is returned. If the time is less than or equal to zero, the method * will not wait at all. * * <p>In this implementation, as this method is an explicit * interruption point, preference is given to responding to the * interrupt over normal or reentrant acquisition of the lock, and * over reporting the elapse of the waiting time. * * @param timeout the time to wait for the lock * @param unit the time unit of the timeout argument * @return {@code true} if the lock was free and was acquired by the * current thread, or the lock was already held by the current * thread; and {@code false} if the waiting time elapsed before * the lock could be acquired * @throws InterruptedException if the current thread is interrupted * @throws NullPointerException if the time unit is null * 經過sync,獲取鎖,可中斷,可超時 */ public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { return sync.tryAcquireNanos(1, unit.toNanos(timeout)); } /** * Attempts to release this lock. * * <p>If the current thread is the holder of this lock then the hold * count is decremented. If the hold count is now zero then the lock * is released. If the current thread is not the holder of this * lock then {@link IllegalMonitorStateException} is thrown. * * @throws IllegalMonitorStateException if the current thread does not * hold this lock */ public void unlock() {//這裏的release方法其實也是AQS的一個模板方法,會回調子類的tryRelease(int arg)方法。 sync.release(1); } // 其餘代碼省略幾百行。。。。 }
而後翻翻jdk源碼 會發現 ReentrantReadWriteLock ,CountDownLatch,Semaphore 也是AQS實現的java
下面看看https://my.oschina.net/u/146130/blog/881848app