⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 service.html

📁 Concurrent Programming in Java
💻 HTML
字号:
<html><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><html> <head><title>Service Threads</title></head><BODY bgcolor=#ffffee vlink=#0000aa link=#cc0000><h1>Service Threads</h1>A service thread is the thread-based analog of a single method.Nearly any method of any class can be transformed into a standaloneservice runnable in a thread, although some cases are of coursesimpler and/or more appropriate than others.  The best candidates aremethods that:<ul>  <li> Are intrinsically time-consuming enough that thread construction       <a href="when.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/when.html">overhead</a> is not a major concern, but       still have finite expected duration.       (In cases where the method intrinsically loops forever, use       the otherwise similar <a href="auton.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/auton.html"> Autonomous Loop</a>       Thread pattern.)   <li> Can be performed independently of other actions; in the simplest       cases, without any intervention by or notification to clients       once they are started.  <li> Perform a <EM>single stateless       service</EM>. A ``single stateless service object'' is one in which       the worker is initialized with values that hold throughout its       lifetime, and its lifetime is confined to performing a single task.  <li> Ideally, are      <em>communication-closed</em>, that is they do not interact with any      other existing visible objects in the course of performing their      tasks. Such services are simpler to reuse across different contexts.  <li> Are independent enough from other classes and methods       to be defined as stand-alone classes. (If this is not       true, consider the generally similar       <a href="waiters.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/waiters.html"> Waiter</a> pattern that       leaves an original class intact,        placing more burden on <code>Runnables</code> of a somewhat different       form.)  <li> Can be invoked from multiple contexts, so are worth packaging up as       classes. (If not, again consider using <a href="waiters.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/waiters.html">       Waiter</a>  threads.)</ul><p> If you are starting with a design in which there already existsone or more methods in some class that you'd like to turn intorunnable standalone services, the easiest approach istransformational. (If this is not the case, just skip ahead a fewparagraphs.) For a classic example, suppose you started out withclass:<pre>class FileIO {  ...  public void writeBytes(String fileName, byte[] data) { ... }  public void readBytes(String fileName, byte[] data) { ... }}</pre><blockquote>(Note: While this makes for a good example of how to build servicethreads, it would be a fairly odd class in Java since it doesn't meshwell with java.io classes that are <em>already</em> structured in waysthat make IO convenient to perform within threads.)</blockquote><p> Both of these methods might be good candidates for service threadssince File I/O can be time-consuming, but can often be doneindependently of callers.<p> To transform any method into a service thread, build a stand-aloneclass that:<ul>  <li> Implements Runnable, so can be run as a thread.  <li> Holds the arguments to the transformed methods as instance       variables.  <li> Performs the indicated method with the supplied arguments       as the body of its <code>run()</code> method.</ul><p>A client can then obtain this service by instantiating the<code>Runnable</code>, wrapping it in a thread, and thencalling <code>start</code>.<p> For example, to transform <code>FileIO.writeBytes</code>into a service thread class:<pre>class FileWriter implements Runnable {  String nm_; byte d_[];   public FileWriter(String name, byte[] data) { nm_ = name; d_ = data; }  public synchronized void write() { /* ... write the file .. */ }  public void run() { write(); } }</pre><p>This could be used, for example, by an object that needed tosave image data in a file while at the same time rendering it:<pre>class ImageManipulator {  ...  void processImage(byte rawImage[]) {    (new Thread(new FileWriter("imageCache", rawImage))).start();    renderImage(rawImage);    ...  }}</pre><p><H2> <a name="secCallbacks"></a>Completion Callbacks</H2>Notice that the <code>FileWriter</code> class above would have to bewritten in a way that caught all possible <code>IOExceptions</code>associated with the write, and probably simply fail if any arethrown. This might not be an acceptable solution.<p> More generally, thread activities that bear any kind of result orstatus reply that the caller might be interested in need some way toget those results to the caller.  This can be done by establishinga <EM>callback</EM> from the thread to the client. Acallback method is just an ordinary method in the client that isdesigned to be called in some special circumstance by the server;here, in the case of completion or failure termination.  To provide ahandle for the callback, the client must send <code>this</code> as oneof the arguments to the request setting up the service thread.<p> To continue the above example, suppose we'd like to also definethe a <CODE>FileReader</CODE> as a standalone service thread class,whose objects read in an entire file asynchronously.  The client mightwant to be notified when the file has been read in so it can startusing the read-in data. It might also need to know if any problemsarise in the attempted read.  Each of these can be encoded ascallbacks.<p> First, to set things up, when using callbacks, it is almost alwaysa good idea to establish <code>interfaces</code> describing thecallback methods, so that the server can be used by any kind of classthat supports those methods. Additionally, you can supply analternative no-callback version of such a class (via an alternativeconstructor) so that clients that do not need notification do not haveto support the interface:<PRE>interface FileReaderClient {  public void readCompleted(FileReader f);  public void readFailed(FileReader f, int errorCode);}class FileReader implements Runnable {  String nm_; byte d_[];   FileReaderClient client_;  int errorCode_;   // constructor for callback version  public FileReader(String name, byte data[], FileReaderClient client) {          nm_ = name; d_ = data; client_ = client; }  // constructor for no-callback version  public FileReader(String name, byte data[]) {          nm_ = name; d_ = data; client_ = null; }  public synchronized void read() {         /* try to read the file ... */         if (/* any problems */ ) {          if (client_ != null) client_.readFailed(nm_, errorCode_);        }        else {          if (client_ != null) client_.readCompleted(nm_);        }  }  public void run() { read(); }}class Application implements FileReaderClient {  private byte data_[];  public void readCompleted(String fn) { /* ... use data... */ }  public void readFailed(String fn, int errorCode) { /* ... fail... */ }  public void app() {    ...    FileReader f = new FileReader("afile", data_, this);    (new Thread(f)).start();    ...  }  ...}</PRE><p> Note: This callback subpattern can be used in any kind ofthread-based design, not just service threads. Similarly, the <ahref="waiters.html#secJoin" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/waiters.html#secJoin">Joining</a> subpattern introduced inconjunction with Waiter threads can be used here to wait out or aborta service thread.<H2> <a name="Gateways"></a>Gateways</H2>A ``gateway'' class repackages an original class that has been splitapart into service threads back into a single entity.  In gateways,each method in the main gateway object constructs a service thread toasynchronously perform the task associated with the method.<p> (Gateway designs are instances of the <a href="early.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/early.html">EarlyReply</a> pattern, but are closely tied to the practice ofestablishing servise threads.)<p> This style, especially when used in conjunction with the <ahref="acceptor.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/acceptor.html"> Acceptor</a> pattern is often used for objectsthat accept messages from other processes, leading to a``thread-per-incoming-message'' design.  Spawning off a threadimmediately to perform a self-contained but time-consuming serviceensures that the gateway object is ready to receive other incomingrequests almost immediately, thus minimizing service latency. This isthe most common way of setting up general-purpose servers. <p> Gateway designs are a Thread-based analog of the <EM>Factory</EM>design pattern (See the <AHREF="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; or for a quick introduction, see <ahref="ifc.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/ifc.html">here</a>). The gateway serves as a factory for theworker objects that do the real work. The main difference is that afactory constructs an object and then returns a handle to it, while agateway constructs an object and then runs it. <p> For example, we canreconstruct our original <code>FileIO</code> class as:<pre>class FileIOV2 {  ...  public void writeBytes(String fileName, byte[] data) {    (new Thread (new FileWriter(fileName, data)).start();      public void readBytes(String fileName, byte[] data) {    (new FileReader("afile", data_, null)).start();  }  // can also support callback version....  public void readBytes(String fileName, byte[] data, FileReaderClient c) {    (new FileReader("afile", data_, c)).start();  }}</pre>    <h3>Variants</h3>Instead of using gateways, it is possible to structure such classesinstead as straight factories, returning references to<code>Runnables</code> that clients can then <code>start()</code>themselves.<p> When gateways spawn so many threads that performance startsbecoming a problem, you can apply the techniques for <ahref="early.html#secLimiting" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/early.html#secLimiting"> Limiting numbers of active threads</a>introduced in conjunction with Early Replies.<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:27:20 EST 1996<!-- hhmts end --></body> </html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -