?? acceptor.html
字號:
<html><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><html> <head><title>MetaObject Acceptors</title></head><BODY bgcolor=#ffffee vlink=#0000aa link=#cc0000><h1>MetaObject Acceptors</h1>A meta-object design is one in which one object receives messagesin some form or another that it decodes into method calls toone or more underlying normal ``ground'' objects.Especially when objects communicate with other processes on othermachines, meta-object designs can be used to perform concurrencycontrol in the process of dispatching incoming messages.<p> Among the most general forms of an acceptor is an <ahref="models.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/models.html">interpretor</a> design running as an <ahref="auton.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/auton.html"> autonomous loop</a>:<pre>class Acceptor { MessageInputStream s; void execute(Message m) { /* ... call some method on some object ... */ /* (perhaps within its own new thread) */ } public void run() { for (;;) { execute(s.readMessage()); /* (or optionally buffer in a queue consumed by execute()) */ } }}</pre>Where <code>Message</code> is just a standin for any kind oftype, including:<ul> <li> A string representation of an incoming request and its arguments (as used in <code>Applet.getParameter</code>). <li> A CORBA-style Request packet. <li> A <code>Runnable</code> object (in which case the <code>execute</code> method just asks the object to <code>run</code> itself). <li> An integer encoding some kind of event. <li> One or more native Java bytecode instructions. <li> ...</ul><p> In principle, using MetaObjects for concurrency control is theideal design form, since it enables the most flexible controlmechanisms. The <code>execute</code> method can look at the entirestate of the program if need be when deciding whether an object is ina state that it should perform a method; otherwise perhaps queuing themessage for later.<p> However, in practice the overhead and awkwardness of ``goingmeta'' is too overwhelming to take seriously unless you<em>already</em> need to create an acceptor for some other reason,such as:<ul> <li> You are hand-crafting your own distributed object system. (See for example <A HREF="javascript:if(confirm('http://www.cs.wustl.edu/~schmidt/Active-Objects.ps.Z \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://www.cs.wustl.edu/~schmidt/Active-Objects.ps.Z'" tppabs="http://www.cs.wustl.edu/~schmidt/Active-Objects.ps.Z">Lavender and Schmidt's Active Object pattern</A>). <li> You are implementing general -purpose network services. (See related <a href="javascript:if(confirm('http://www.cs.wustl.edu/~schmidt \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://www.cs.wustl.edu/~schmidt'" tppabs="http://www.cs.wustl.edu/~schmidt"> patterns by Doug Schmidt</a>), in which case you will need to further decompose this pattern to arrange for connection management, etc. <li> You are building a special purpose interpretor communicating via sockets to another set of programs (e.g., database facilities.) <li> You are implementing some form of <A HREF="javascript:if(confirm('http://www.omg.org/ \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://www.omg.org/'" tppabs="http://www.omg.org/">CORBA</A> <EM>Object adapter</EM>, in which case you implement only the <code>execute</code> portion, after receiving the Message (Request) from some master acceptor. <li> You are writing any other form of command interpretor.</ul>In all of these cases, the implementation of <code>execute</code> caninclude synchronization control done on behalf of the ground objects,exactly as done in the <a href="coordinators.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/coordinators.html">Coordinator</a>pattern (which is identical to Acceptor except that Coordinators donot need to interpret requests, they just delegate them.)<H2><A NAME="secEvents"></A>Event Loops</H2>Event loops are a way to organize the request-decoding aspects ofsmall-scale MetaObject-style designs, without (necessarily) dealingwith exernal request sources. Event loops ``continuously'' acceptrequest messages from local objects and dispatch them to other objectsor methods. They also typically differ from true MetaObjects in thatthe requests take a simple, specialized form; for example, integersrepresenting keystrokes or mouse events. <P>Normally, event loops are intended to run asynchronously with respectto objects posting events (although not necessarily with respect tothose servicing them). Thus, the loop should run as a <AHREF="javascript:if(confirm('http://g.oswego.edu/dl/pats/javaconc.html \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://g.oswego.edu/dl/pats/javaconc.html'" tppabs="http://g.oswego.edu/dl/pats/javaconc.html">Thread</A>.Additionally, you can buffer new event requests so that eventproducers do not have to wait for others to be processed.<P> Buffering can be done by separating the roles of event acceptorand event dispatcher into two objects. The Event Acceptor is theobject that event producers communicate with. It merely depositsevents in a buffer. The Event Dispatcher implements the dispatchingloop as a separate thread. It continuously pulls requests from thebuffer, (<CODE>wait</CODE>ing if there are no requests) and processesthem. The resulting classes implement a classic buffered producerconsumer design. For example, a simple version (using the <ahref="javascript:if(confirm('http://g.oswego.edu/dl/classes/collections \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://g.oswego.edu/dl/classes/collections'" tppabs="http://g.oswego.edu/dl/classes/collections"> collectionspackage</a> for its data structures) looks like:<PRE>// use java.awt.Event, or a more specialized version such asclass MyEvent { public int eventCode; ... }public class EventAcceptor { private collections.Bag buff_; private EventDispatcher ed_; public EventAcceptor() { buff_ = new collections.CircularList(); ed_ = new EventDispatcher(this); new Thread(ed_).start(); } public synchronized void event(MyEvent e) { buff_.add(e); notify(); } synchronized Event next() { waitUntilNonEmpty(); MyEvent e = null; try { e = (MyEvent)(buff_.take()); } catch (NoSuchElementException canthappen) {} return e; } private synchronized void waitUntilNonEmpty() { while (buff_.size() != 0) try { wait(); } catch(InterruptedException ex) {}; }}public class EventDispatcher implements Runnable { protected EventAcceptor es_; EventDispatcher(EventAcceptor es) { es_ = es; } protected void execute(MyEvent e) { switch (e.eventCode) { case 1: ... break; ... } } public void run() { for (;;) { MyEvent e = es_.next(); execute(e); } }}</PRE>For illustration, <CODE>notify()</CODE> was used here instead of<CODE>notifyAll</CODE> in the <CODE>event</CODE> method because atmost one thread will be waiting for a new event to be added. Thiswould make it impossible (or at least exceedingly difficult) to builda subclass with multithreaded dispatching. <h3>Handlers</h3>The above design is not terribly extensible since the<code>EventDispather</code> must be ``born'' knowing how to handleeach incoming event. A more flexible version can be constructed byrecasting <code>execute</code> to work off tables or other adjustablemechanisms that delegate event-handling actions to dynamicallyinstalled <em>handlers</em>. For example:<pre>public interface MyEventHandler { // As with Applet action() conventions, return false if could not handle boolean handle(MyEvent e); }public class TableDrivenEventDispatcher extends EventDispatcher { collections.UpdatableMap table_; TableDrivenEventDispatcher(EventAcceptor es) { super(es); table = new collections.HashedMap(); } protected void execute(MyEvent e) { collections.Bag b = (collections.Bag)(table_.at(new Integer(e.eventCode))); if (b != null) { for (Enumeration e = b.elements(); e.hasMoreElements(); ) { MyEventHandler h = (MyEventHandler)(e.nextElement()); h.handle(e); } } } public void addHandler(int event, MyEventHandler h) { Integer i = new Integer(e.eventCode); collections.Bag b; if (table_.includesKey(i)) b = (collections.Bag)(table_.at(i)); else { b = new collections.LinkedBuffers(); table_.add(i, b); } b.add(h); } }</pre>To maximized flexibility, the table entries themsleves hold bags ofhandlers, allowing more than one handler per event type. Within<code>execute</code>, all are handlers associated with the recievedevent are tried. (This is a variant of a <em>Cascade</em> -- see the<A HREF="javascript:if(confirm('http://st-www.cs.uiuc.edu/users/patterns/Books.html \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://st-www.cs.uiuc.edu/users/patterns/Books.html'" tppabs="http://st-www.cs.uiuc.edu/users/patterns/Books.html"> DesignPatterns</A> book.) An alternative design would be to continue tryinghandlers until hitting the first one that returns <code>true</code>.<p><a href="aopintro.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/aopintro.html">[Concurrent Programming in Java]</a><hr><address><A HREF="javascript:if(confirm('http://g.oswego.edu/dl \n\nThis file was not retrieved by Teleport Pro, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?'))window.location='http://g.oswego.edu/dl'" tppabs="http://g.oswego.edu/dl">Doug Lea</A></address><!-- hhmts start -->Last modified: Tue Feb 20 06:28:59 EST 1996<!-- hhmts end --></body> </html>
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -