`

Active Object

 
阅读更多

        Active Object Pattern是由很多组件构成的,是一个大型的Pattern。适合大规模问题。

        首先由Client发出请求,Active Object的参与者配合得到请求的返回值。

         Active Object中,首先异步消息都传递给Proxy,Proxy将这些消息放在队列里面,然后由一个线程(Scheduler)不断的获取这些消息,让这些消息交给“提货单”,真正的消息处理工作交给Servant,Servant把结果交给“提货单”,最后结果返回到Client。

         下面的示例展示了这个过程(不过是一个小规模的问题)。

          示例中:消息有makeString和displayString,首先是一个生产者和消费者模型,队列中没消息时获取消息就得等待,队列满了时插入消息也要等待。displayString的工作采用了Thread Per Message Pattern,makeString的工作则用FuturePattern。

         

下面是详细代码:

         Result类是一个虚拟数据参与者,它有两个子类:Future参与者FutureResult和RealResult。这里实际用到了Future Pattern。(FutureResult中一旦设置了Result,马上通知别人(提货单)可以获取Result,“提货单”是MakeStringRequest,注意其中的:future.setResult(result);)。

package activeobject;
public abstract class Result {
	public abstract Object getResultValue();
}

 

package activeobject;
public class RealResult extends Result {
	private final Object resultValue;
	public RealResult(Object resultValue){
		this.resultValue=resultValue;
	}
	@Override
    public Object getResultValue(){
    	return resultValue;
    }
}

 

package activeobject;
public class FutureResult extends Result {
	private Result result;
	public boolean ready=false;
	public synchronized void setResult(Result result){
		this.result=result;
		this.ready=true;
		notifyAll();
	}
	public synchronized Object getResultValue(){
		while(!ready){
			try{
				wait();
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
		return result.getResultValue();
	}
}

 

        MethodRequest类是一个抽象化的请求。具体的请求是其子类MakeStringRequest、DisplayRequest。
MethodRequest中的字段servant用来进行实际处理的Servant实例,字段future用来存放设置返回值的FutureResult实例,如果请求不需要返回,这个域为空。servant和future都可以让子类来处理,故声明为protected。
        MakeStringRequest会设置servant和future,执行execute时候让servant生成一个Result,这个Result是RealResult,是makeString的结果,makeString是一个需要时间的操作,操作完才能得到RealResult。得到结果后马上设置FutureResult的结果,这个FutureResult之前就是Proxy中定义的,然后返回给Client,但由于没有设置RealResult,它只能陷入等待,所以,得到RealResult后,Client才能继续运行。
        DisplayRequest让servant显示字符串,其实,也就是Client发请求,通过Proxy(将消息传递给队列),队列(请求缓存站)后交给servant执行,也就是Thread Per Message模型了。

package activeobject;
 abstract class MethodRequest {
	protected final Servant servant;
	protected final FutureResult future;
	protected MethodRequest(Servant servant,FutureResult future){
		this.servant=servant;
		this.future=future;
	}
	public abstract void execute();
}

 

package activeobject;
public class MakeStringRequest extends MethodRequest{
    private final int count;
    private final char fillchar;
    public MakeStringRequest(Servant servant,FutureResult future,int count ,char fillchar){
    	super(servant,future);
    	this.count=count;
    	this.fillchar=fillchar;
    }
    public void execute(){
    	Result result=servant.makeString(count,fillchar);
    	future.setResult(result);
    }
}

 

package activeobject;
public class DisplayStringRequest extends MethodRequest {
    private final String string;
    public DisplayStringRequest(Servant servant,String string){
    	super(servant,null);
    	this.string=string;
    }
    public void execute(){
    	servant.displayString(string);
    }
}

 
        接口ActiveObject有产生Result(makeString)和显示字符串的虚方法。

        Servant类实现了这个接口,它先生成一个String,然后将String包装成RealResult。(这是一个耗时的过程),以及显示一个字符串。当然,Servant是实际处理请求的类。
        Proxy也实现了ActiveObject接口,有字段scheduler和servant。它的makeString是向队列中添加制造请求,它的displayString是向队列中添加显示请求。 这个类本质上是将Client的工作与执行的工作分开,充当了“启动”的作用。即“分离方法的启动(invocation)和执行(execution)”

        Proxy将Client的请求给SchedulerThread(字段schedule),Scheduler有一个ActivationQueue属性,它有两个工作:将请求添加到队列(ActivationQueue)中;不断的从队列中得到请求,然后执行。

          ActivationQueue有一个MethodRequest队列,当队列满了时,添加元素等待,队列为空时,移走一个元素等待。

package activeobject;
public interface ActiveObject {
	public abstract Result makeString(int count,char fillchar);
	public abstract void displayString(String string);
}

 

package activeobject;
public class Servant implements ActiveObject{
	@Override
	public void displayString(String string) {
		try{
			System.out.println("displayString:"+string);
			Thread.sleep(10);
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}

	@Override
	public Result 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));
	}
}

 

package activeobject;
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 void displayString(String string) {
		scheduler.invoke(new DisplayStringRequest(servant,string));
	}
	@Override
	public Result makeString(int count, char fillchar) {
		FutureResult future=new FutureResult();
		scheduler.invoke(new MakeStringRequest(servant,future,count,fillchar));
		return future;
	}
}

 

package activeobject;
public class SchedulerThread extends Thread{
    private final ActivationQueue queue;
    public SchedulerThread(ActivationQueue queue){
    	this.queue=queue;
    }
    public void invoke(MethodRequest request){
    	queue.putRequest(request);
    }
    @Override
    public void run(){
    	while(true){
    		MethodRequest request=queue.takeRequest();
    		request.execute();
    	}
    }
}

 

package activeobject;
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;
	}
}

 

这里有一个ActiveObjectFactory类,它是为接口提供一个简便的“外观”,它用来产生一个Proxy对象,当然与这个对象相关的Servant、SchedulerThread、Queue都产生了,并且线程SchedulerThread也开启了,这个线程是不断的处理请求,而Client中的线程是不断的发出请求,让Proxy将请求加到队列中。

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;
	}
}

 

这个模型中的整个类图如下:



测试类(发出请求的Client)如下:

package activemain;
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);
	}
	@Override
    public void run(){
		try{
			for(int i=0;true;i++){
				Result result=activeObject.makeString(i, fillchar);
				Thread.sleep(10);
				String value=(String)result.getResultValue();
				System.out.println(Thread.currentThread().getName()+":value="+value);
			}
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}

 

package activemain;
import activeobject.ActiveObject;

public class DisplayClientThread extends Thread{
	private final ActiveObject activeObject;;
	public DisplayClientThread(String name,ActiveObject activeObject){
		super(name);
		this.activeObject=activeObject;
	}
	@Override
    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();
		}
	}

}

 

package activemain;
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",activeObject).start();
	}
}

 程序执行的结果:

Bobby:value=
displayString:Chris  0
Alice:value=
displayString:Chris  1
Bobby:value=B
Alice:value=A
displayString:Chris  2
Bobby:value=BB
Alice:value=AA
displayString:Chris  3
Bobby:value=BBB
Alice:value=AAA
displayString:Chris  4
Bobby:value=BBBB
Alice:value=AAAA
displayString:Chris  5
Bobby:value=BBBBB
Alice:value=AAAAA
Bobby:value=BBBBBB
displayString:Chris  6
Alice:value=AAAAAA
displayString:Chris  7
Bobby:value=BBBBBBB
Alice:value=AAAAAAA
displayString:Chris  8
Bobby:value=BBBBBBBB
Alice:value=AAAAAAAA
displayString:Chris  9
Bobby:value=BBBBBBBBB
Alice:value=AAAAAAAAA
displayString:Chris  10
Bobby:value=BBBBBBBBBB
displayString:Chris  11
Alice:value=AAAAAAAAAA
Bobby:value=BBBBBBBBBBB
Alice:value=AAAAAAAAAAA
displayString:Chris  12
Bobby:value=BBBBBBBBBBBB

 

        这个模式处理的问题是:当多个Client使用不安全的Servant,且Servant相应的时间比较久,这回拖垮Client的响应性。

 

 

 

 

  • 大小: 175.7 KB
分享到:
评论

相关推荐

    ActiveObject

    在IT领域,"Active Object"是一种设计模式,它在并发编程中被广泛使用,尤其是在分布式系统和实时系统中。Active Object模式的主要目的是解决多线程环境中的同步问题,提高代码的可读性和可维护性。 在传统的并发...

    ActiveObject.pdf

    ### Java中的ActiveObject:一种基于Convention Over Configuration的ORM框架 #### 概述 在Java领域,ActiveObject是一种受到Ruby on Rails框架中ActiveRecord启发而设计的轻量级对象关系映射(ORM)工具。它的...

    ActiveObject 对象 Msxml2.DOMDocument 详解

    本文将深入探讨ActiveObject中的一个关键对象——Msxml2.DOMDocument,以及它在ASP.NET AJAX WebService中的应用。 Msxml2.DOMDocument是Microsoft XML库(MSXML)中的核心组件,它实现了W3C的Document Object ...

    Active Object技术讲解

    ### Active Object技术详解 #### 一、Active Object (AO) 技术概览 Active Object (AO) 技术是一种用于构建并发程序的设计模式,它主要用于简化多线程编程中的复杂性,尤其适用于嵌入式系统和实时系统。在AO模型中...

    ActiveObject模板

    ActiveObject是一种设计模式,主要应用于并发编程环境,特别是在多线程或多进程的系统中。它是一种行为设计模式,旨在解决对象在并发环境下的同步问题,同时保持对象接口的简单性和线程安全。ActiveObject模式的核心...

    FreeRTOS 结合 Active Object Demo Project

    "FreeAct" is a minimal real-time embedded framework (RTEF) based ... FreeAct implemetns the Active Object design pattern. It was originally presented by Miro Samek at the Embedded Online Conference 2020

    Python Active Object Server-开源

    Python Active Object Server(PAOS)是一个开源项目,旨在提供一种机制,使得Python对象可以通过网络进行交互和事件通知。这个服务器不仅允许对象之间的通信,还包含了对事件处理和对象缓存的管理,使得开发者能够...

    Active Object real-time OS:AO RTOS是基于Active Object并发模型的小型实时OS-开源

    **Active Object并发模型** Active Object(也称为Actor模型)是一种并发编程模型,它将对象视为独立的计算实体,每个对象都有自己的执行线程,并通过消息传递进行通信。在AO RTOS中,这种模型被用于创建高效、实时...

    非ie内核浏览器ACTIVEX插件+火狐谷歌支持OBJECT

    当OBJECT标签指向一个ActiveX对象时,它会检查当前浏览器是否支持ActiveX。如果支持,控件会被加载;如果不支持,可以提供备选的HTML5或者JavaScript代码来替代ActiveX的功能。这种方法需要对浏览器的兼容性有深入...

    Object Restore for Active Directory_10

    大家经常会在维护AD的同时有可能误删除用户,OU... QUEST Object Restore for Active Directory(这是QUEST很少的免费软件之一,相比QUEST Recovery Manager for Active Directory功能弱很多,但是我们还是可以使用到)

    symbian资料

    这份PDF课件很可能详细介绍了如何在Symbian平台上使用和实现Active Object,包括其原理、优点、如何创建和管理Active Object,以及在实际应用中的最佳实践。 因此,从这个压缩包中,我们可以学习到以下关键知识点:...

    ACE资料_PPT

    "ACE资料_PPT"这个压缩包文件主要包含了与ACE(Active Concurrency Environment)相关的学习资料,其中"Active Object.pdf"和"ACE资料"是两个重要的组成部分。ACE是一个开源的、跨平台的软件框架,主要用于构建高...

    C++多线程编程_框架

    `ActiveObject.cpp`和`ActiveObject.h`可能涉及到Active Object设计模式。这种模式用于在多线程环境中封装对象的行为,每个Active Object都有自己的工作线程,以处理来自其他线程的请求。这有助于避免线程间的直接...

    Symbian手机开发与应用

    《ActiveObject.pdf》则专门讨论了Symbian中的Active Object设计模式,这是Symbian异步编程的核心。Active Object允许开发者在非阻塞的情况下处理长时间运行的任务,从而优化系统性能并提升用户体验。 此外,包含的...

    Object segmentation using graph cuts based active contours相关文章

    "Object segmentation using graph cuts based active contours"是利用图割(Graph Cuts)算法和主动轮廓(Active Contours,也称Snake模型)相结合的一种高效分割方法。本文将深入探讨这两种技术及其在图像分割中的...

    Java敏捷持久层-ROR-ActiveRecord持久层框架的Java实现

    以“ActiveObject”为例,这可能是某个Java实现ActiveRecord模式的框架的名字。它可能提供了类似于以下的API: ```java public class User extends ActiveObject { private String username; private String ...

    Symbian编程总结-基础篇-活动对象正解

    在Symbian操作系统中,活动对象(Active Object)是一个核心概念,用于处理异步操作,尤其是在需要长时间运行或非阻塞的任务中。活动对象不是线程,而是与线程无关的实体,它允许开发者在不阻塞主线程的情况下执行...

    Chrome调用ocxDemo

    1. **ActiveX控件(OCX)**:OCX是微软开发的一种控件技术,它是基于OLE(Object Linking and Embedding)的,用于Windows应用程序中添加自定义功能。这些控件可以嵌入到HTML页面中,通过Internet Explorer或其他支持...

Global site tag (gtag.js) - Google Analytics