KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > cluster > util > SingleRemoveSynchronizedAddLock


1 /*
2  * Copyright 1999,2004 The Apache Software Foundation.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16
17 package org.apache.catalina.cluster.util;
18
19 /**
20  * The class <b>SingleRemoveSynchronizedAddLock</b> implement locking for accessing the queue
21  * by a single remove thread and multiple add threads.
22  *
23  * A thread is only allowed to be either the remove or
24  * an add thread.
25  *
26  * The lock can either be owned by the remove thread
27  * or by a single add thread.
28  *
29  * If the remove thread tries to get the lock,
30  * but the queue is empty, it will block (poll)
31  * until an add threads adds an entry to the queue and
32  * releases the lock.
33  *
34  * If the remove thread and add threads compete for
35  * the lock and an add thread releases the lock, then
36  * the remove thread will get the lock first.
37  *
38  * The remove thread removes all entries in the queue
39  * at once and proceeses them without further
40  * polling the queue.
41  *
42  * The lock is not reentrant, in the sense, that all
43  * threads must release an owned lock before competing
44  * for the lock again!
45  *
46  * @author Rainer Jung
47  * @author Peter Rossbach
48  * @version 1.1
49  */

50  
51 public class SingleRemoveSynchronizedAddLock {
52     
53     public SingleRemoveSynchronizedAddLock() {
54     }
55     
56     public SingleRemoveSynchronizedAddLock(boolean dataAvailable) {
57         this.dataAvailable=dataAvailable;
58     }
59     
60     /**
61      * Time in milliseconds after which threads
62      * waiting for an add lock are woken up.
63      * This is used as a safety measure in case
64      * thread notification via the unlock methods
65      * has a bug.
66      */

67     private long addWaitTimeout = 10000L;
68
69     /**
70      * Time in milliseconds after which threads
71      * waiting for a remove lock are woken up.
72      * This is used as a safety measure in case
73      * thread notification via the unlock methods
74      * has a bug.
75      */

76     private long removeWaitTimeout = 30000L;
77
78     /**
79      * The current remove thread.
80      * It is set to the remove thread polling for entries.
81      * It is reset to null when the remove thread
82      * releases the lock and proceeds processing
83      * the removed entries.
84      */

85     private Thread JavaDoc remover = null;
86
87     /**
88      * A flag indicating, if an add thread owns the lock.
89      */

90     private boolean addLocked = false;
91
92     /**
93      * A flag indicating, if the remove thread owns the lock.
94      */

95     private boolean removeLocked = false;
96
97     /**
98      * A flag indicating, if the remove thread is allowed
99      * to wait for the lock. The flag is set to false, when aborting.
100      */

101     private boolean removeEnabled = true;
102
103     /**
104      * A flag indicating, if the remover needs polling.
105      * It indicates, if the locked object has data available
106      * to be removed.
107      */

108     private boolean dataAvailable = false;
109
110     /**
111      * @return Value of addWaitTimeout
112      */

113     public synchronized long getAddWaitTimeout() {
114         return addWaitTimeout;
115     }
116
117     /**
118      * Set value of addWaitTimeout
119      */

120     public synchronized void setAddWaitTimeout(long timeout) {
121         addWaitTimeout = timeout;
122     }
123
124     /**
125      * @return Value of removeWaitTimeout
126      */

127     public synchronized long getRemoveWaitTimeout() {
128         return removeWaitTimeout;
129     }
130
131     /**
132      * Set value of removeWaitTimeout
133      */

134     public synchronized void setRemoveWaitTimeout(long timeout) {
135         removeWaitTimeout = timeout;
136     }
137
138     /**
139      * Check if the locked object has data available
140      * i.e. the remover can stop poling and get the lock.
141      * @return True iff the lock Object has data available.
142      */

143     public synchronized boolean isDataAvailable() {
144         return dataAvailable;
145     }
146
147     /**
148      * Check if an add thread owns the lock.
149      * @return True iff an add thread owns the lock.
150      */

151     public synchronized boolean isAddLocked() {
152         return addLocked;
153     }
154
155     /**
156      * Check if the remove thread owns the lock.
157      * @return True iff the remove thread owns the lock.
158      */

159     public synchronized boolean isRemoveLocked() {
160         return removeLocked;
161     }
162
163     /**
164      * Check if the remove thread is polling.
165      * @return True iff the remove thread is polling.
166      */

167     public synchronized boolean isRemovePolling() {
168         if ( remover != null ) {
169             return true;
170         }
171         return false;
172     }
173
174     /**
175      * Acquires the lock by an add thread and sets the add flag.
176      * If any add thread or the remove thread already acquired the lock
177      * this add thread will block until the lock is released.
178      */

179     public synchronized void lockAdd() {
180         if ( addLocked || removeLocked ) {
181             do {
182                 try {
183                     wait(addWaitTimeout);
184                 } catch ( InterruptedException JavaDoc e ) {
185                 }
186             } while ( addLocked || removeLocked );
187         }
188         addLocked=true;
189     }
190
191     /**
192      * Acquires the lock by the remove thread and sets the remove flag.
193      * If any add thread already acquired the lock or the queue is
194      * empty, the remove thread will block until the lock is released
195      * and the queue is not empty.
196      */

197     public synchronized boolean lockRemove() {
198         removeLocked=false;
199         if ( ( addLocked || ! dataAvailable ) && removeEnabled ) {
200             remover=Thread.currentThread();
201             do {
202                 try {
203                     wait(removeWaitTimeout);
204                 } catch ( InterruptedException JavaDoc e ) {
205                 }
206             } while ( ( addLocked || ! dataAvailable ) && removeEnabled );
207             remover=null;
208         }
209         if ( removeEnabled ) {
210             removeLocked=true;
211         }
212         return removeLocked;
213     }
214
215     /**
216      * Releases the lock by an add thread and reset the remove flag.
217      * If the reader thread is polling, notify it.
218      */

219     public synchronized void unlockAdd(boolean dataAvailable) {
220         addLocked=false;
221         this.dataAvailable=dataAvailable;
222         if ( ( remover != null ) && ( dataAvailable || ! removeEnabled ) ) {
223             remover.interrupt();
224         } else {
225             notifyAll();
226         }
227     }
228
229     /**
230      * Releases the lock by the remove thread and reset the add flag.
231      * Notify all waiting add threads,
232      * that the lock has been released by the remove thread.
233      */

234     public synchronized void unlockRemove() {
235         removeLocked=false;
236         dataAvailable=false;
237         notifyAll();
238     }
239
240     /**
241      * Abort any polling remover thread
242      */

243     public synchronized void abortRemove() {
244         removeEnabled=false;
245         if ( remover != null ) {
246             remover.interrupt();
247         }
248     }
249
250 }
251
Popular Tags