Active Object模式
Active Object介绍
Active Object模式,介绍了一种多线程环境下,多对象之间共同协作完成任务的方法;该模式综合了:Producer-Consumer模式、Thread-Per Message模式、Future 模式、Thread-Specific Storage模式;
Active Object使用场景
- 以多线程的内部实现方式,对外提供功能点;
- Active Object开启了通往分布式的序幕;
Active Object示例代码
//Future模式里表示结果的类
public abstract class Result<T> {
public abstract T getResultValue();
}
//真实的结果——包含数据
public class RealResult<T> extends Result<T> {
private final T resultValue;
public RealResult(T resultValue){
this.resultValue=resultValue;
}
@Override
public T getResultValue(){
return resultValue;
}
}
//获取真实结果的凭据
public 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();
}
@Override
public synchronized T getResultValue(){
while(!ready){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
return result.getResultValue();
}
}
//该类对外提供API
public interface ActiveObject {
Result<String> makeString(int count,char fillChar);
void displayString(String string);
}
//任务的实际执行者,实现了ActiveObject接口
public class Servant implements ActiveObject {
@Override
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){
e.printStackTrace();
}
}
return new RealResult<>(new String(buffer));
}
@Override
public void displayString(String string) {
try{
System.out.println("displaySting: "+string);
Thread.sleep(10);
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
//对方法的包装——请求
public 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();
}
//显示字符串的请求
public class DisplayStringRequest extends MethodRequest<Object> {
private final String string;
protected DisplayStringRequest(Servant servant,String string) {
super(servant, null);
this.string=string;
}
@Override
public void execute() {
servant.displayString(string);
}
}
//生成字符串的请求
public class MakeStringRequest extends MethodRequest<String> {
private final int count;
private final char fillChar;
protected MakeStringRequest(Servant servant, FutureResult<String> future,int count,char fillChar) {
super(servant, future);
this.count=count;
this.fillChar=fillChar;
}
@Override
public void execute() {
Result<String> result=servant.makeString(count,fillChar);
future.setResult(result);
}
}
//该类相当于Producer-Consumer中的Channel,负责缓存请求
public 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){
e.printStackTrace();
}
}
requestQueue[tail]=request;
tail=(tail+1)%requestQueue.length;
count++;
notifyAll();
}
public synchronized MethodRequest takeRequest(){
while(count<=0){
try{
wait();
}catch(InterruptedException e){
e.printStackTrace();
}
}
MethodRequest request=requestQueue[head];
head=(head+1)%requestQueue.length;
count--;
notifyAll();
return request;
}
}
//Client看到的ActiveObject,代理类,具体任务由servant执行
public class Proxy implements ActiveObject {
private final SchedulerThread scheduler;
private final Servant servant;
public Proxy(SchedulerThread scheduler,Servant servant){
this.scheduler=scheduler;
this.servant=servant;
}
@Override
public Result<String> makeString(int count, char fillChar) {
FutureResult<String> future=new FutureResult<String>();
scheduler.invoke(new MakeStringRequest(servant,future,count,fillChar));
return future;
}
@Override
public void displayString(String string) {
scheduler.invoke(new DisplayStringRequest(servant,string));
}
}
//方法调用的线程——负责收集请求,然后调用
public class SchedulerThread extends Thread {
private final ActivationQueue queue;
public 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();
}
}
}
//生成ActiveObject的工厂——注意,生成ActiveObject的时候,也启动了Schedule线程,返回的是代理类
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;
}
}
//发送显示命令的线程
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){
e.printStackTrace();
}
}
}
///发送生成命令的线程
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){
e.printStackTrace();
}
}
}
//启动类——创建两条生成线程,一条显示线程,共享同一个ActiveObject;
public class Tester {
public static void main(String[] args){
ActiveObject activeObject=ActiveObjectFactory.createActiveObject();
new MakerClientThread("Alice",activeObject).start();
new MakerClientThread("Bobby",activeObject).start();
new DisplayClientThread("Chris",activeObject).start();
}
}
整体的思路如下:
Active Object理解
Client通过Active Object提供的API使用Active Object提供的功能;但是Active Object并不是一个人在战斗;它组合了调用转换、请求管理、请求执行等功能;实现了调用和执行的分离;
这里,Active Object模式不但体现了OOP中的“封装”,还组合多种多线程设计模式,体现出其综合性;
Active Object实现了跨线程的功能实现;相同的思路,通过配合网络及serialization技术,便可以更好滴理解分布式流程;