//先拿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实现的