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的响应性。
相关推荐
在IT领域,"Active Object"是一种设计模式,它在并发编程中被广泛使用,尤其是在分布式系统和实时系统中。Active Object模式的主要目的是解决多线程环境中的同步问题,提高代码的可读性和可维护性。 在传统的并发...
### Java中的ActiveObject:一种基于Convention Over Configuration的ORM框架 #### 概述 在Java领域,ActiveObject是一种受到Ruby on Rails框架中ActiveRecord启发而设计的轻量级对象关系映射(ORM)工具。它的...
本文将深入探讨ActiveObject中的一个关键对象——Msxml2.DOMDocument,以及它在ASP.NET AJAX WebService中的应用。 Msxml2.DOMDocument是Microsoft XML库(MSXML)中的核心组件,它实现了W3C的Document Object ...
### Active Object技术详解 #### 一、Active Object (AO) 技术概览 Active Object (AO) 技术是一种用于构建并发程序的设计模式,它主要用于简化多线程编程中的复杂性,尤其适用于嵌入式系统和实时系统。在AO模型中...
ActiveObject是一种设计模式,主要应用于并发编程环境,特别是在多线程或多进程的系统中。它是一种行为设计模式,旨在解决对象在并发环境下的同步问题,同时保持对象接口的简单性和线程安全。ActiveObject模式的核心...
"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(PAOS)是一个开源项目,旨在提供一种机制,使得Python对象可以通过网络进行交互和事件通知。这个服务器不仅允许对象之间的通信,还包含了对事件处理和对象缓存的管理,使得开发者能够...
**Active Object并发模型** Active Object(也称为Actor模型)是一种并发编程模型,它将对象视为独立的计算实体,每个对象都有自己的执行线程,并通过消息传递进行通信。在AO RTOS中,这种模型被用于创建高效、实时...
当OBJECT标签指向一个ActiveX对象时,它会检查当前浏览器是否支持ActiveX。如果支持,控件会被加载;如果不支持,可以提供备选的HTML5或者JavaScript代码来替代ActiveX的功能。这种方法需要对浏览器的兼容性有深入...
大家经常会在维护AD的同时有可能误删除用户,OU... QUEST Object Restore for Active Directory(这是QUEST很少的免费软件之一,相比QUEST Recovery Manager for Active Directory功能弱很多,但是我们还是可以使用到)
这份PDF课件很可能详细介绍了如何在Symbian平台上使用和实现Active Object,包括其原理、优点、如何创建和管理Active Object,以及在实际应用中的最佳实践。 因此,从这个压缩包中,我们可以学习到以下关键知识点:...
"ACE资料_PPT"这个压缩包文件主要包含了与ACE(Active Concurrency Environment)相关的学习资料,其中"Active Object.pdf"和"ACE资料"是两个重要的组成部分。ACE是一个开源的、跨平台的软件框架,主要用于构建高...
`ActiveObject.cpp`和`ActiveObject.h`可能涉及到Active Object设计模式。这种模式用于在多线程环境中封装对象的行为,每个Active Object都有自己的工作线程,以处理来自其他线程的请求。这有助于避免线程间的直接...
《ActiveObject.pdf》则专门讨论了Symbian中的Active Object设计模式,这是Symbian异步编程的核心。Active Object允许开发者在非阻塞的情况下处理长时间运行的任务,从而优化系统性能并提升用户体验。 此外,包含的...
"Object segmentation using graph cuts based active contours"是利用图割(Graph Cuts)算法和主动轮廓(Active Contours,也称Snake模型)相结合的一种高效分割方法。本文将深入探讨这两种技术及其在图像分割中的...
以“ActiveObject”为例,这可能是某个Java实现ActiveRecord模式的框架的名字。它可能提供了类似于以下的API: ```java public class User extends ActiveObject { private String username; private String ...
在Symbian操作系统中,活动对象(Active Object)是一个核心概念,用于处理异步操作,尤其是在需要长时间运行或非阻塞的任务中。活动对象不是线程,而是与线程无关的实体,它允许开发者在不阻塞主线程的情况下执行...
1. **ActiveX控件(OCX)**:OCX是微软开发的一种控件技术,它是基于OLE(Object Linking and Embedding)的,用于Windows应用程序中添加自定义功能。这些控件可以嵌入到HTML页面中,通过Internet Explorer或其他支持...