KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sapia > ubik > util > StartStopLock


1 package org.sapia.ubik.util;
2
3 /**
4  * An instance of this class is used to synchronized start/stop operations. It is common for such operations
5  * to be wholly or in part performed in separate threads. An instance of this class can be used to
6  * synchronized threads that invoke start or stop operations, and those that actually perform these
7  * operations.
8  * <p>
9  * USAGE:
10  * <p>
11  * Suppose we are implementing a server that can be embedded. The server itself will run in a
12  * separate thread. The application that will use the server will be responsible for starting and
13  * stopping it.
14  * <p>
15  * First, our server thread implementation:
16  * <pre>
17  * public class ServerThread extends Thread{
18  * private StartStopLock _lock
19  *
20  * public ServerThread(StartStopLock lock){
21  * _lock = lock;
22  * }
23  *
24  * public void run(){
25  *
26  * boolean started = false;
27  * while(!_lock.stopRequested && !interrupted()){
28  * if(!started){
29  * _lock.notifyStarted(null);
30  * started = true;
31  * }
32  * // do work...
33  * }
34  *
35  * // here do shutdown stuff...
36  *
37  * _lock.notifyStopped(null);
38  * }
39  * }
40  * </pre>
41  * <p>
42  * Third, we create the actual server class that will be used by application code:
43  * <pre>
44  * public class Server{
45  * private StartStopLock _lock = new StartStopLock();
46  * private ServerThread _thread;
47  *
48  * public void start() throws Exception{
49  * _thread = new ServerThread(_lock);
50  * _thread.start();
51  * _lock.waitStarted();
52  * }
53  *
54  * public void stop() throws Exception{
55  * _thread.interrupt();
56  * _lock.triggerStopped();
57  * _lock.waitStopped();
58  * }
59  * }
60  * </pre>
61  * <p>
62  *
63  *
64  *
65  * @author Yanick Duchesne
66  *
67  * <dl>
68  * <dt><b>Copyright:</b><dd>Copyright &#169; 2002-2005 <a HREF="http://www.sapia-oss.org">Sapia Open Source Software</a>. All Rights Reserved.</dd></dt>
69  * <dt><b>License:</b><dd>Read the license.txt file of the jar or visit the
70  * <a HREF="http://www.sapia-oss.org/license.html">license page</a> at the Sapia OSS web site</dd></dt>
71  * </dl>
72  */

73 public class StartStopLock {
74   
75   public boolean started, stopped, stopRequested;
76   
77   private Throwable JavaDoc _startErr, _stopErr;
78   
79   private StopRequestListener _listener;
80   
81   
82   /**
83    * @param listener a <code>StopRequestListener</code> that is called
84    * upon this instance's <code>triggerStop</code> method being called.
85    *
86    * @see StopRequestListener
87    */

88   public StartStopLock(StopRequestListener listener){
89     _listener = listener;
90   }
91
92   public StartStopLock(){
93   }
94   
95   /**
96    * @return <code>true</code> if the <code>started</code> flag is on.
97    */

98   public boolean isStarted(){
99     return started;
100   }
101
102   /**
103    * @return <code>true</code> if the <code>stopped</code> flag is on.
104    */

105   public boolean isStopped(){
106     return stopped;
107   }
108   
109   /**
110    * @return <code>true</code> if the <code>stopRequested</code> flag is on.
111    */

112   public boolean isStopRequested(){
113     return stopRequested;
114   }
115   
116   /**
117    * This method internally sets the <code>stopRequested</code> flag
118    * to <code>true</code>, calls this instance's encapsulated
119    * <code>StopRequestListener</code>, and notifies threads that are
120    * currently blocking on the <code>waitStopped()</code> method.
121    */

122   public synchronized void triggerStop(){
123     stopRequested = true;
124     
125     if(_listener != null){
126       try{
127         _listener.onStopRequested();
128       }catch(Throwable JavaDoc t){
129         notifyStopped(t);
130         return;
131       }
132     }
133     notifyStopped(null);
134   }
135   
136   /**
137    * Blocks until this instance's <code>started</code> flag is set to <code>true</code>,
138    * or until a startup error is signaled. If the given timeout has elapsed, this method exits.
139    *
140    * @see #notifyStarted(Throwable)
141    *
142    * @param timeout a given amount of time to wait for this instance's
143    * <code>started</code> flag to be <code>true</code>.
144    * @throws InterruptedException if the calling thread is interrupted while blocking.
145    * @throws Throwable if an error occurs at startup.
146    */

147   public synchronized void waitStarted(long timeout) throws InterruptedException JavaDoc, Throwable JavaDoc{
148     while(!started && _startErr == null){
149       wait(timeout);
150     }
151     if(_startErr != null)
152       throw _startErr;
153   }
154   
155   /**
156    * Blocks until this instance's <code>started</code> flag is set to <code>true</code>,
157    * or until a startup error is signaled.
158    *
159    * @see #notifyStarted(Throwable)
160    *
161    * @throws InterruptedException if the calling thread is interrupted while blocking.
162    * @throws Throwable if an error occurs at startup.
163    */

164   public synchronized void waitStarted() throws InterruptedException JavaDoc, Throwable JavaDoc{
165     while(!started && _startErr == null){
166       wait();
167     }
168     if(_startErr != null)
169       throw _startErr;
170   }
171
172   /**
173    * Blocks until this instance's <code>stopped</code> flag is set to <code>true</code>,
174    * or until a startup error is signaled. If the given timeout has elapsed, this method exits.
175    *
176    * @see #notifyStopped(Throwable)(Throwable)
177    *
178    * @param timeout a given amount of time to wait for this instance's
179    * <code>stopped</code> flag to be <code>true</code>.
180    * @throws InterruptedException if the calling thread is interrupted while blocking.
181    * @throws Throwable if an error occurs while stopping.
182    */

183   public synchronized void waitStopped(long timeout) throws InterruptedException JavaDoc, Throwable JavaDoc{
184     while(!stopped && _stopErr == null){
185       wait(timeout);
186     }
187     if(_stopErr != null)
188       throw _stopErr;
189   }
190   
191   /**
192    * Blocks until this instance's <code>stopped</code> flag is set to <code>true</code>,
193    * or until a startup error is signaled.
194    *
195    * @see #notifyStopped(Throwable)
196    *
197    * @throws InterruptedException if the calling thread is interrupted while blocking.
198    * @throws Throwable if an error occurs while stopping.
199    */

200   public synchronized void waitStopped() throws InterruptedException JavaDoc, Throwable JavaDoc{
201     while(!stopped && _stopErr == null){
202       wait();
203     }
204     if(_stopErr != null)
205       throw _stopErr;
206   }
207   
208   /**
209    * @param err a <code>Throwable</code>
210    */

211   public synchronized void notifyStarted(Throwable JavaDoc err){
212     _startErr = err;
213     if(err == null){
214       started = true;
215     }
216     notifyAll();
217   }
218   
219   /**
220    * @param err a <code>Throwable</code>
221    */

222   public synchronized void notifyStopped(Throwable JavaDoc err){
223     _stopErr = err;
224     if(err == null){
225       stopped = true;
226     }
227     notifyAll();
228   }
229   
230   public interface StopRequestListener{
231       public void onStopRequested() throws Throwable JavaDoc;
232   }
233
234 }
235
Popular Tags