📄 delegnotif.html
字号:
<html><!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN"><html> <head><title>Delegating Notifications</title></head><BODY bgcolor=#ffffee vlink=#0000aa link=#cc0000><h1>Delegating Notifications</h1>Synchronization notifications can be organized along the lines of the<A HREF="javascript:if(confirm('http://g.oswego.edu/dl/pats/early.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/early.html#secSubj'" tppabs="http://g.oswego.edu/dl/pats/early.html#secSubj">subject/observer</A> pattern in which:<ul> <li> <em>Subjects</em> (or even the ``subject'' aspects of any object) maintain some state (normally as instance variables). <li> <em>Observers</em> (or, again, just the ``observer'' aspects of any object) must take some action when subjects change state in certain ways. <li> Subjects may have multiple observers, and vice-versa. <li> When a subject changes state, it sends a change notification to the observer(s). <li> When an observer receives a state-change notification, it probes for details to find out whether that state change actually requires any action, and if so, performs it.</ul>In fact, the standard use of <CODE>notifyAll</CODE> may be seen as asimplification of this pattern in which the subject and observer arethe same object: The <CODE>notifyAll</CODE> method acts as a changenotification, alerting other threads that a value has beenupdated. The notified tasks must complete the full check to see if thechange affects their status. <P><p> When all of these roles in the subject/observer pattern arelocalized within a single object, then the built-in<code>notifyAll</code> mechanisms suffice to control behavior. Butwhen synchronization conditions are spread out across multipleobjects, you can to extend these mechanisms in accord with asubject/observer scheme, often simplifying down those aspects ofsubject/observer that need not apply (for example restricting subjectsto have at most one observer).<p> To illustrate with a slightly stripped down example, suppose wemaintained the <CODE>count_</CODE> variable from the <ahref="synchDesign.html#secCounter" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/synchDesign.html#secCounter">BoundedCounter</a> example in alittle <CODE>NotifyingInt</CODE> object referencing a single observer(the <CODE>BoundedCounter</CODE>) that it notifies on update:<PRE>class NotifyingInt { private int value_; private Object ob_; public synchronized int value() { return value_; } public synchronized void value(int v) { value_ = v; ob_.notifyAll();} public NotifyingInt(Object ob, int v) { ob_ = ob; value_ = v; }}class BoundedCounterV3 implements BoundedCounter { public synchronized int value() { return c_.value(); } public synchronized void inc() { waitUntilIncrementable(); c_.value(c_.value()+1); } public synchronized void dec() { waitUntilDecrementable(); c_.value(c_.value()-1); } public BoundedCounterV3() { c_ = new NotifyingInt(this, minValue); } private NotifyingInt c_; private synchronized void waitUntilIncrementable() { while (c_.value() >= maxVal) try { wait(); } catch(InterruptedException ex) {}; } private synchronized void waitUntilDecrementable() { while (c_.value() <= minVal) try { wait(); } catch(InterruptedException ex) {}; }}</PRE>When guards intrinsically rely on many properties of many objects,such notification structures can become quite complex. To stem this,use Mediator designs (as described in 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). <P>Notification techniques involving other objects can only be guaranteedto work as expected when these other objects are under the exclusivecontrol of the host (i.e., in the above example, ensuring that each<CODE>BoundedCounterV3</CODE> owns a <CODE>NotifyingInt</CODE> thatnever receives messages from any other object), and/or when waitconditions are entirely based on <ahref="latches.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/latches.html"><EM>latches</EM></a>, which, once set to a valuenever change again. When applicable, the use of latch-basedconditions is the simplest and best way to avoid errors andcomplications in designs where synchronization depends on the states ofmultiple, non-exclusively controlled objects.<p> Otherwise, since the other objects may receive messages in betweenthe condition test and the action, they could get into inconsistentstates. If guards really must reference volatile properties ofobjects that are not under exclusive control, then you have to treatthe check-and-act sequence as a <ahref="trans.html" tppabs="http://www.foi.hr/~dpavlin/java/mirrors/g.oswego.edu/dl/pats/trans.html"><EM>transaction</EM></a>. As with othertransaction-based designs, this raises the issue of whether and how todeal with cases where one of the other objects is engaging in atime-consuming <CODE>synchronized</CODE> method during a conditioncheck by the host. If the property-checking accessor method is<CODE>synchronized</CODE>, then the host object will wait for thisother method to complete in order to invoke the accessor. Worse,imposing waits inside condition checks sometimes leads to deadlockproblems. For example, if two objects both have guards that refer toeach others properties, they may deadlock while checking each other'sstate via <CODE>synchronized</CODE> accessors. <P><p>One general kind of solution to this kind of problem is toset up a second-level locking scheme distinguishing between <em>reading</em>(checking state via accessors) and <em>writing</em> (changingstate via update methods). (<em>To be continued</em>).<p> Particular solutions for other concurrency problems of this formexist. For example, the famous <ahref="javascript:if(confirm('http://www.eng.uci.edu/~bgloyer/hotjava/DiningPhilosophers.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://www.eng.uci.edu/~bgloyer/hotjava/DiningPhilosophers.html'" tppabs="http://www.eng.uci.edu/~bgloyer/hotjava/DiningPhilosophers.html">Dining Philosophers</a> problem.<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:29:00 EST 1996<!-- hhmts end --></body> </html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -