概述
接受異步消息的主動對象。
Java的java.lang.Thread類的實例就是一種主動對象。
主動對象可以從外部接收和處理異步消息并根據需要返回處理結果翠订。
Active Object模式中的主動對象會通過自己特有的線程在合適的時機處理從外部接收到的異步消息摩骨。
Active Object模式有時也稱Actor模式驳规。
示例程序
使用的類
- Main 測試程序行為的類
- MakerClientThread 發(fā)出“生成字符串”請求的線程
- DisplayClientThread 發(fā)出“顯示字符串”請求的線程
- ActiveObject 定義“主動對象”的接口(API)的接口
- ActiveObjectFactory 創(chuàng)建“主動對象”的類
- Proxy 將方法調用轉換為MethodRequest對象的類(實現(xiàn)了ActiveObject的接口)
- SchedulerThread 調用execute 方法處理 MethodRequest 對象的類
- ActivationQueue 按順序保存MethodRequest對象的類
- MethodRequest 表示請求的抽象類
- MakeStringRequest makeString方法(生成字符串)對應的類秉沼。MethodRequest類的子類
- DisplayStringRequest displayString方法(顯示字符串)對應的類州刽。MethodRequest類的子類
- Result 表示執(zhí)行結果的抽象類
- FutureResult 在Future 模式中表示執(zhí)行結果的類
- RealResult 表示實際的執(zhí)行結果的類
- Servant 執(zhí)行實際處理的類(實現(xiàn)了ActiveObject接口)
Main 類
import activeobject.ActiveObject;
import activeobject.ActiveObjectFactory;
public class Main {
public static void main(String[] args) {
ActiveObject activeObject = ActiveObjectFactory.createActiveObject();
new MakerClientThread("Alice", activeObject).start();
new MakerClientThread("Bobby", activeObject).start();
new DisplayClientThread("Chris", acvtiveObject).start();
}
}
MakerClientThread 類
import activeobject.ActiveObject;
import activeobject.Result;
public class MakerClientThread extends Thread {
private final ActiveObject activeObject;
private final char fillchar;
public MakerClientThread(String name, ActiveObject activeObject){
super(name);
this.activeObject = activeObject;
this.fillchar = name.charAt(0);
}
public void run(){
try {
for(int i = 0; true; i++){
Result<String> result = activeObject.makeString(i, fillchar);
Thread.sleep(10);
String value = result.getResultValue();
System.out.println(Thread.currentThread().getName() + ": value = " + value);
}
} catch (InterruptedException e){}
}
}
DisplayClientThread 類
import activeobject.ActiveObject;
import activeobject.Result;
public class DisplayClientThread extends Thread {
private final ActiveObject activeObject;
public DisplayClientThread(String name, ActiveObject activeObject){
super(name);
this.activeObject = activeObject;
}
public void run() {
try {
for( int i = 0; true; i++){
String string = Thread.currentThread().getName() + " " + i;
activeObject.displayString(string);
Thread.sleep(200);
}
} catch(InterruptedException e) {}
}
}
ActiveObject 接口
package activeobject;
public interface ActiveObject {
public abstract Result<String> makeString (int count, char fillchar);
public abstract void displayString(String string);
}
ActiveObjectFactory 類
package activeobject;
public class ActiveObjectFactory {
public static ActiveObject createActiveObject() {
Servant servant = new Servant();
ActivationQueue queue = new ActivationQueue();
SchedulerThread scheduler = new SchedulerThread(queue);
Proxy proxy = new Proxy(scheduler, servant);
scheduler.start();
return proxy;
}
}
Proxy 類
package activeobject;
class Proxy implements ActiveObject {
private final SchedulerThread scheduler;
private final Servant servant;
public Proxy(SchedulerThread scheduler, Servant servant) {
this.scheduler = scheduler;
this.servant = servant;
}
public Result<String> makeString(int count, char fillchar){
FutureResult<String> future = new FutureResult<String>();
scheduler.invoke(new MakeStringRequest<servant, future, count, fillchar));
return future;
}
public void displayString(String string){
scheduler.invoke(new DisplayStringRequest(servant, string));
}
}
ScheduelrThread 類
package activeobject;
class SchedulerThread extends Thread {
private final ActivationQueue queue;
private SchedulerThread(ActivationQueue queue){
this.queue = queue;
}
public void invoke(MethodRequest request){
queue.putRequest(request);
}
public void run(){
while (true) {
MethodRequest request = queue.takeRequest();
request.execute();
}
}
}
ActivationQueue 類
package activeobject;
class ActivationQueue {
private static final int MAX_METHOD_REQUEST = 100;
private final MethodRequest[] requestQueue;
private int tail;
private int head;
private int count;
public ActivationQueue(){
this.requestQueue = new MethodRequest[MAX_METHOD_REQUEST];
this.head = 0;
this.tail = 0;
this.count = 0;
}
public synchronized void putRequest(MethodRequest request){
while(count >= requestQueue.length){
try{
wait();
} catch (InterruptedException e) {}
}
requestQueue[tail] = request;
tail = (tail + 1) % requestQueue.length;
count++;
notifyAll();
}
public synchronized MethodRequest takeRequest() {
while (count <= 0 ){
try{
wait();
} catch (InterruptedException e){}
}
MethodRequest request = requestQueue[head];
head = (head + 1) % requestQueue.length;
count--;
notifyAll();
return request;
}
}
主動對象方 MethodRequest類`
package activeobject;
abstract class MethodRequest<T> {
protected final Servant servant;
protected final FutureResult<T> future;
protected MethodRequest(Servant servant, FutureResult<T> future){
this.servant = servant;
this.future = future;
}
public abstract void execute():
}
主動對象方 MakeStringRequest 類
package activeobject;
class MakeStringRequest extends MethodRequest<String> {
private final int count;
private final char fillchar;
public MakeStringRequest(Servant servant, FutureResult<String> future, int Count, char fillchar) {
super(servant, future);
this.count = count;
this.fillchar = fillchar;
}
public void execute() {
Result<String> result = servant.makeString(Count, fillchar);
future.setResult(result);
}
}
主動對象方 DisplayStringRequest 類
package activeobject;
class DisplayStringRequest extends MethodRequest<Object> {
private final String string;
public DisplayStringRequest(Servant servant, String string){
super(servant, null);
this.string =string;
}
public void execute() {
servant.displayString(string);
}
}
主動對象方 Result 類
package activeobject;
public abstract class Result<T> {
public abstract T getResultValue();
}
主動對象方 FutureResult 類
package activeobject;
class FutureResult<T> extends Result<T> {
private Result<T> result;
private boolean ready = false;
public synchronized void setResult(Result<T> result) {
this.result = result;
this.ready = true;
notifyAll();
}
public synchronized T getResultValue() {
while ( !ready ) {
try {
wait();
} catch (InterruptedException e) {}
}
return result.getResultValue();
}
}
主動對象方 Servant 類
package activeobject;
class Servant implements ActiveObject {
public Result<String> makeString(int count , char fillchar) {
char[] buffer = new char[Count];
for (int i = 0 ; i < count; i++) {
buffer[i] = fillchar;
try { Thread.sleep(100); } catch (InterruptedException e) {}
}
return new RealResult<String>(new String(buffer));
}
public void displayString(String string){
try {
System.out.print("displayString: " + string);
} catch(InterruptedException e) {}
}
}
ActiveObject 模式中的角色
- Client(委托者)
Client角色調用ActiveObject對象的方法來委托處理呕寝,它能夠調用的只有ActiveObject 角色提供的方法勋眯。調用這些方法后,程序控制權會立即返回下梢。 - ActiveObject(主動對象)
ActiveObject對象定義了主動對象向Client角色提供的接口(API)客蹋。 - Proxy(代理人)
Proxy角色負責將方法調用轉換為MethodRequest角色的對象。轉換后的MethodReques角色會傳遞給Scheduler角色孽江。 - Scheduler
Scheduler角色負責將Proxy角色傳遞來的MethodRequest角色傳遞給ActivationQueue角色讶坯,以及從ActivationQueue角色取出并執(zhí)行MethodRequest角色這兩項工作。 - MethodRequest
MethodRequest角色是與來自Client角色的請求對應的角色岗屏。MethodRequest定義了負責執(zhí)行處理的Servant角色辆琅,以及負責設置返回值的Future角色和負責執(zhí)行請求的方法(execute)。 - ConcreteMethodRequest
ConcreteMethodRequest角色是使用MethodRequest角色與具體的方法相對應的角色这刷。 - Servant(仆人)
Servant角色負責實際地處理請求婉烟。
調用Servant角色的是Scheduler角色的線程。Scheduler角色會從ActivationQueue角色取出一個MethodRequest角色并執(zhí)行它暇屋。此時似袁,Scheduler角色調用的是Servant角色的方法。
Servant角色實現(xiàn)了ActiveObject角色定義的接口(API)咐刨。
Proxy角色會將請求轉換為MethodRequest角色昙衅,而Servant角色則會實際地執(zhí)行該請求。Scheduler角色介于Proxy角色和Servant角色之間定鸟,負責管理按照什么順序執(zhí)行請求而涉。
ActivationQueue(主動隊列)
ActivationQueue 角色是保存MethodRequest角色的類。
調用putRequest方法的是Client角色的線程联予,而調用takeRequest方法的是Scheduler角色的線程啼县。這里使用了Producer-Consumer模式材原。VirtualResult(虛擬結果)
VirtualResult角色與Future角色、RealResult角色共同構成了Future模式谭羔。
Client角色在獲取處理結果時會調用VirtualResult角色的getResultValue方法华糖。Future(期貨)
Future角色時Client角色在獲取處理結果時實時調用的角色麦向。當處理結果還沒出來的時候瘟裸,它會使用Guarded Suspension模式讓Client角色的線程等待結果出來。RealResult(真實結果)
RealResult角色是表示處理結果的角色诵竭。Servant角色會創(chuàng)建一個RealResult角色作為處理結果话告。然后調用Future角色的setRealResult方法將其設置到Future角色中。