模板方法模式在JDK源码里最典型的实现就是AQS
AbstractQueuedSynchronizer
AQS(AbstractQueuedSynchronizer)的部分代码如下:
public abstract class AbstractQueuedSynchronizer
extends AbstractOwnableSynchronizer
implements java.io.Serializable {
// ……代码省略……
public final void acquire(int arg) {
if (!tryAcquire(arg) &&
acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
public final boolean release(int arg) {
if (tryRelease(arg)) {
Node h = head;
if (h != null && h.waitStatus != 0)
unparkSuccessor(h);
return true;
}
return false;
}
// ……代码省略……
protected boolean tryAcquire(int arg) {
throw new UnsupportedOperationException();
}
protected boolean tryRelease(int arg) {
throw new UnsupportedOperationException();
}
// ……代码省略……
}
ReentrantLock关于AQS两个抽象方法的实现:
public class ReentrantLock implements Lock, java.io.Serializable {
// ……代码省略……
abstract static class Sync extends AbstractQueuedSynchronizer {
private static final long serialVersionUID = -5179523762034025860L;
@ReservedStackAccess
protected final boolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
throw new IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
}
/**
* Sync object for non-fair locks
*/
static final class NonfairSync extends Sync {
protected final boolean tryAcquire(int acquires) {
return nonfairTryAcquire(acquires);
}
}
/**
* Sync object for fair locks
*/
static final class FairSync extends Sync {
@ReservedStackAccess
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;
}
}
// ……代码省略……
}
注意acquire()和release()方法用final关键字修饰,不可修改,而tryAcquire()和tryRelease()这两个用protected关键词修饰的方法则直接抛了异常,所以它们必须由子类去实现。acquire()和release()方法定义了一个统一的结构,差异化的tryAcquire()和tryRelease()方法需要具体的子类去实现功能,实现了模板方法模式。
模板方法模式在很多框架中也有应用,比如Junit 单元测试啦、HttpSerlvet 中关于 doGet()、doPost() 等方法的调用啦、Spring 中 JDBCTemplate啦等等。