模板方法模式,AQS源码
一.介绍
模板方法模式实际上就是相当于,将一些共有的方法和属性放在父类即抽象类里,然后将一些变化的方法,即可能形成多态特性的方法放在子类里。
1.先定义一个模板抽象类,在抽象类里定义一个通用的方法,即比较固定的方法,称为模板方法。
2.定义一些抽象的方法,具体给子类实现,在模板方法里调用这些抽象方法。形成一个固定的逻辑。
3.定义子类,具体去实现这些抽象方法。
二.UML图
三.代码
publicabstractclass AbstractTemplate {publicvoid doBussiness(){step1();
step2();
specialStep1();
specialStep2();
step3();
}
protectedvoid step1(){System.out.println(
"第一步");}
protectedvoid step2(){System.out.println(
"第二步");}
protectedvoid step3(){System.out.println(
"第三步");}
protectedabstractvoid specialStep1();protectedabstractvoid specialStep2();}
publicclass ConcreteTemplate extends AbstractTemplate {@Override
protectedvoid specialStep1() {System.out.println(
"ConcreteTemplate"+"specialStep1");}
@Override
protectedvoid specialStep2() {System.out.println(
"ConcreteTemplate"+"specialStep2");}
}
publicclass ConcreteTemplate1 extends AbstractTemplate {@Override
protectedvoid specialStep1() {System.out.println(
"ConcreteTemplate1"+"specialStep1");}
@Override
protectedvoid specialStep2() {System.out.println(
"ConcreteTemplate1"+"specialStep2");}
publicclass AppMain {publicstaticvoid main(String[] args) {AbstractTemplate temp1
= new ConcreteTemplate();temp1.doBussiness();
AbstractTemplate temp2
= new ConcreteTemplate1();temp2.doBussiness();
}
}
输出:
第一步
第二步
ConcreteTemplatespecialStep1
ConcreteTemplatespecialStep2
第三步
第一步
第二步
ConcreteTemplate1specialStep1
ConcreteTemplate1specialStep2
第三步
四:AQS里模板方法的运用
ReentrantLock内部使用了AQS来实现加锁释放锁功能,其中有公平锁和非公平锁。ReentrantLock内部有一个内部类Sync,这个类继承至AQS。AQS里的acquire方法就相当于一个模板方法,即排他获取资源的方法,里面调用了tryAcquire等未实现的虚方法。Sync类通过重写AQS里的方法来实现具体的线程同步逻辑。而非公平锁NonfairSync和公平锁FairSync都继承至Sync。Sync重写了AQS里的tryRelease方法,将公平锁和非公平锁统一,而公平锁和非公平锁的获取锁逻辑不同
所以在NonfairSync和FairSync内部实现了不同的具体的tryAcquire方法。
AbstractQueuedSynchronizer.java
publicfinalvoid acquire(int arg) {if (!tryAcquire(arg) &&acquireQueued(addWaiter(Node.EXCLUSIVE), arg))
selfInterrupt();
}
ReentrantLock.java
publicvoid lock() {sync.lock();
}
publicvoid unlock() {sync.release(
1);}
ReentrantLock.Sync
abstractstaticclass Sync extends AbstractQueuedSynchronizer {finalboolean nonfairTryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {if (compareAndSetState(0, acquires)) {setExclusiveOwnerThread(current);
returntrue;}
}
elseif (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0) // overflowthrownew Error("Maximum lock count exceeded");
setState(nextc);
returntrue;
}
returnfalse;
}
protectedfinalboolean tryRelease(int releases) {
int c = getState() - releases;
if (Thread.currentThread() != getExclusiveOwnerThread())
thrownew IllegalMonitorStateException();
boolean free = false;
if (c == 0) {
free = true;
setExclusiveOwnerThread(null);
}
setState(c);
return free;
}
}
ReentrantLock.FairSync
staticfinalclass FairSync extends Sync {finalvoid lock() {acquire(
1);}
protectedfinalboolean tryAcquire(int acquires) {final Thread current = Thread.currentThread();int c = getState();if (c == 0) {if (!hasQueuedPredecessors() &&compareAndSetState(
0, acquires)) {setExclusiveOwnerThread(current);
returntrue;}
}
elseif (current == getExclusiveOwnerThread()) {int nextc = c + acquires;if (nextc < 0)thrownew Error("Maximum lock count exceeded");setState(nextc);
returntrue;}
returnfalse;}
}
ReentrantLock.FairSync
staticfinalclass NonfairSync extends Sync {finalvoid lock() {if (compareAndSetState(0, 1))setExclusiveOwnerThread(Thread.currentThread());
elseacquire(
1);}
protectedfinalboolean tryAcquire(int acquires) {return nonfairTryAcquire(acquires);}
}
五:总结
通过上面可以看出ReentrantLock调用lock方法加锁,这个lock方法实际上是调用的Sync类里的lock方法,而lock方法在NonfairSync和FairSync里被覆盖
lock方法里又调用了AQS的模板方法acquire, acquire里又调用了tryAcquire 方法,tryAcquire 方法在NonfairSync和FairSync分别被覆盖,从而实现了不同的获取锁逻辑。
Sync
以上是 模板方法模式,AQS源码 的全部内容, 来源链接: utcz.com/a/74964.html