?? early.html
字號(hào):
System.out.println(String.valueOf(subj_.state()); } public Observer(Subject s) { subj_ = s; cachedState_ = s.state(); display(); }}</PRE>For a multithreaded version, we can recast<CODE>Observer.update</CODE> as trigger for its asynchronousstate-checks and redisplays:<PRE>class Updater implements Runnable { private Observer o_; public void run() { o_.doUpdate(); } public Updater(Observer o) { o_ = o; }} class Observer { private int cachedState_; private Subject subj_; public synchronized void update() { (new Thread(new Updater(this)).start(); } synchronized void doUpdate() { int oldState = cachedState_; cachedState_ = subj_.state(); if (oldState != cachedState_) display(); } synchronized void display() { /* ... */ } public Observer(Subject s) { subj_ = s; cachedState_ = s.state(); display(); }}</PRE><h3><a name="secCombine"></a>Combining Classes</h3>In the common case where the helper class does not need to maintainany variables to use in its <code>run</code> method, it's possible tofold the helper class entirely into the main class. For example, thisturns out to be true for <code>Observer</code>, so it is possible tosimplify it down to:<PRE>class Observer implements Runnable { private int cachedState_; private Subject subj_; public synchronized void update() { (new Thread(this).start(); } synchronized void run() { int oldState = cachedState_; cachedState_ = subj_.state(); if (oldState != cachedState_) display(); } synchronized void display() { /* ... */ } public Observer(Subject s) { subj_ = s; cachedState_ = s.state(); display(); }}</PRE><h2><a name="secLimiting"></a>Limiting Thread Construction</h2>You sometimes need to be more careful when using early-reply stylethread construction. At any given time, one object may have spawnedoff several concurrent helper threads, each of which captures a bit ofits state. So, even when all methods are synchronized, in some senses,it is not just doing `one thing at a time'. However when the threadsthemselves do not maintain any `interesting' state and do notinteract, there is often no harm and some good in this, althoughfailing to limit the number of simultaneously active Java threads cansometimes lead to poor performance.<p>Otherwise, the host object should avoid inconsistency problems byensuring that there are at most only some known number of helperthreads executing at a time, where almost always, the `some knownnumber' is exactly one. The simplest and most common way to limit thenumber of active threads to exactly one is to have the object maintaina reference to a single <CODE>Thread</CODE>, and use <AHREF="synchDesign.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/synchDesign.html">guards</A> to wait until it is finished beforespawning off a new activity. <P>For example, in the <CODE>Observer.update</CODE>, if there were somereason that we needed to ensure that new <CODE>display</CODE>activities are not initiated while another one is in progress, wecould use one of the simpler <A HREF="synchDesign.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/synchDesign.html">guard</A>designs, along with the convention that we assign null to the threadreference when it is OK to start a new thread. (<EM>Note:</EM> Moregenerally, it is good Java programming practice to null out threadreferences whenever they aren't needed, so as to enable garbagecollection of the threads. (And even more generally, this applies toinstance variables referencing any kind of object.))<PRE>class Observer implements Runnable { private int cachedState_; private Subject subj_; private Thread updaterThread_; // when null, can start a new one public synchronized void update() { waitForUpdater(); updaterThread_ = new Thread(this); updater_.start(); } synchronized void run() { int oldState = cachedState_; cachedState_ = subj_.state(); if (oldState != cachedState_) display(); updater_ = null; notifyAll(); } synchronized void display() { /* ... */ } synchronized void WaitForUpdater() { while (updater_ != null) { try { wait();} catch (InterruptedException ignore) {} } } public Observer(Subject s) { subj_ = s; cachedState_ = s.state(); updater_ = null; display(); }}</PRE><p> This strategy for limiting thread construction is quite common,especially in Applets, where it's often the case that for eitherefficiency or functionality reasons you want <em>at most</em> one livethread playing music or doing computations or whatever. For example,in the <ahref="javascript:if(confirm('http://g.oswego.edu/dl/applets/micro.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/applets/micro.html'" tppabs="http://g.oswego.edu/dl/applets/micro.html">Microscrope</a> gamementioned when describing <a href="javaconc.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/javaconc.html">thread control</a>the <code>run()</code> method for the slow move finder just nulled outthe thread when it was done, and the <code>startTurn</code> methodrefused to create another unless the old one was finished:<pre> public boolean placing() { return findThread != null; } public void run() { int s = findMove(initialBoard, initialPlayer, runLevel); Move result = new Move(trialBest[runLevel - 1]); ... game.move(result); findThread = null; }</pre><p> (Instead of using wait mechanics here, there was a way for usersto cancel the move finder, which <code>stop()</code>ed the thread,allowing a new one to be created later when the user clicked thebutton again. This made the move finder a bit easier for users tocontrol.)<p> If, instead of exactly one thread, you need to limit to some othernumber, you can use a variant of the <ahref="synchDesign.html#secCounter" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/synchDesign.html#secCounter">BoundedCounter</a> class thatmaintains a set of thread references and hands them out rather thanjust counting them via <code>inc</code> and <code>dec</code>, as donein the running example version of this class.<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:19 EST 1996<!-- hhmts end --></body> </html>
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -