KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jofti > cache > QueryUpdateLock


1 /*
2  * Created on 01-Sep-2005
3  *
4  */

5 package com.jofti.cache;
6
7 import com.jofti.oswego.concurrent.Sync;
8
9
10
11
12 /**
13  
14  * This is an adaptation of Doug Lea's ReaderWriter lock to allow effectively two groups of readers.
15  * Any number of readers in one of the groups can be share one lock, but only one group of readers
16  * can be active at once. The difference is that the writer lock (which was a single entry) now behaves like a read lock
17  * but without the single access restriction.
18  *
19  * @author xenephon (xenephon@jofti.com)
20  *
21  */

22 public class QueryUpdateLock {
23
24       protected class WriterLock extends Signaller
25       implements Sync
26   {
27
28       public void acquire()
29           throws InterruptedException JavaDoc
30       {
31           if(Thread.interrupted())
32               throw new InterruptedException JavaDoc();
33           InterruptedException JavaDoc interruptedexception = null;
34           synchronized(this)
35           {
36               if(!startWriteFromNewWriter())
37                   try
38                   {
39                       do
40                           wait();
41                       while(!startWriteFromWaitingWriter());
42                       return;
43                   }
44                   catch(InterruptedException JavaDoc interruptedexception1)
45                   {
46                       cancelledWaitingWriter();
47                       interruptedexception = interruptedexception1;
48                   }
49           }
50           if(interruptedexception != null)
51           {
52               readerLock_.signalWaiters();
53               throw interruptedexception;
54           } else
55           {
56               return;
57           }
58       }
59
60       public void release()
61       {
62           Signaller signaller = endWrite();
63           if(signaller != null)
64               signaller.signalWaiters();
65       }
66
67       synchronized void signalWaiters()
68       {
69           notify();
70       }
71
72       public boolean attempt(long l)
73           throws InterruptedException JavaDoc
74       {
75           if(Thread.interrupted())
76               throw new InterruptedException JavaDoc();
77           InterruptedException JavaDoc interruptedexception = null;
78           synchronized(this)
79           {
80               if(l <= 0L)
81               {
82                   boolean flag = startWrite();
83                   return flag;
84               }
85               if(startWriteFromNewWriter())
86               {
87                   boolean flag1 = true;
88                   return flag1;
89               }
90               long l1 = l;
91               long l2 = System.currentTimeMillis();
92               do
93               {
94                   try
95                   {
96                       wait(l1);
97                   }
98                   catch(InterruptedException JavaDoc interruptedexception1)
99                   {
100                       cancelledWaitingWriter();
101                       notify();
102                       interruptedexception = interruptedexception1;
103                       break;
104                   }
105                   if(startWriteFromWaitingWriter())
106                   {
107                       boolean flag2 = true;
108                       return flag2;
109                   }
110                   l1 = l - (System.currentTimeMillis() - l2);
111                   if(l1 > 0L)
112                       continue;
113                   cancelledWaitingWriter();
114                   notify();
115                   break;
116               } while(true);
117           }
118           readerLock_.signalWaiters();
119           if(interruptedexception != null)
120               throw interruptedexception;
121           else
122               return false;
123       }
124
125       protected WriterLock()
126       {
127       }
128   }
129
130   protected class ReaderLock extends Signaller
131       implements Sync
132   {
133
134       public void acquire()
135           throws InterruptedException JavaDoc
136       {
137           if(Thread.interrupted())
138               throw new InterruptedException JavaDoc();
139           InterruptedException JavaDoc interruptedexception = null;
140           synchronized(this)
141           {
142               if(!startReadFromNewReader())
143                   try
144                   {
145                       do
146                           wait();
147                       while(!startReadFromWaitingReader());
148                       return;
149                   }
150                   catch(InterruptedException JavaDoc interruptedexception1)
151                   {
152                       cancelledWaitingReader();
153                       interruptedexception = interruptedexception1;
154                   }
155           }
156           if(interruptedexception != null)
157           {
158               writerLock_.signalWaiters();
159               throw interruptedexception;
160           } else
161           {
162               return;
163           }
164       }
165
166       public void release()
167       {
168           Signaller signaller = endRead();
169           if(signaller != null)
170               signaller.signalWaiters();
171       }
172
173       synchronized void signalWaiters()
174       {
175           notifyAll();
176       }
177
178       public boolean attempt(long l)
179           throws InterruptedException JavaDoc
180       {
181           if(Thread.interrupted())
182               throw new InterruptedException JavaDoc();
183           InterruptedException JavaDoc interruptedexception = null;
184           synchronized(this)
185           {
186               if(l <= 0L)
187               {
188                   boolean flag = startRead();
189                   return flag;
190               }
191               if(startReadFromNewReader())
192               {
193                   boolean flag1 = true;
194                   return flag1;
195               }
196               long l1 = l;
197               long l2 = System.currentTimeMillis();
198               do
199               {
200                   try
201                   {
202                       wait(l1);
203                   }
204                   catch(InterruptedException JavaDoc interruptedexception1)
205                   {
206                       cancelledWaitingReader();
207                       interruptedexception = interruptedexception1;
208                       break;
209                   }
210                   if(startReadFromWaitingReader())
211                   {
212                       boolean flag2 = true;
213                       return flag2;
214                   }
215                   l1 = l - (System.currentTimeMillis() - l2);
216                   if(l1 > 0L)
217                       continue;
218                   cancelledWaitingReader();
219                   break;
220               } while(true);
221           }
222           writerLock_.signalWaiters();
223           if(interruptedexception != null)
224               throw interruptedexception;
225           else
226               return false;
227       }
228
229       protected ReaderLock()
230       {
231       }
232   }
233
234   protected abstract class Signaller
235   {
236
237       abstract void signalWaiters();
238
239       protected Signaller()
240       {
241       }
242   }
243
244
245   public QueryUpdateLock()
246   {
247       activeReaders_ = 0L;
248       activeWriters_ = 0l;
249       waitingReaders_ = 0L;
250       waitingWriters_ = 0L;
251   }
252
253   public Sync queryLock()
254   {
255       return writerLock_;
256   }
257
258   public Sync updateLock()
259   {
260       return readerLock_;
261   }
262
263   protected synchronized void cancelledWaitingReader()
264   {
265       waitingReaders_--;
266   }
267
268   protected synchronized void cancelledWaitingWriter()
269   {
270       waitingWriters_--;
271   }
272
273   protected boolean allowReader()
274   {
275       return activeWriters_ <=0l ;
276   }
277   
278   protected boolean allowWriters()
279   {
280       return activeReaders_ <=0l ;
281   }
282
283
284   protected synchronized boolean startRead()
285   {
286       boolean flag = allowReader();
287       if(flag){
288
289           activeReaders_++;
290       }
291       return flag;
292   }
293
294   protected synchronized boolean startWrite()
295   {
296      boolean flag = allowWriters();
297      if(flag){
298
299          
300          activeWriters_++;
301      }
302      return flag;
303   }
304
305   protected synchronized boolean startReadFromNewReader()
306   {
307       boolean flag = startRead();
308       if(!flag){
309           waitingReaders_++;
310       }
311       
312       return flag;
313   }
314
315   protected synchronized boolean startWriteFromNewWriter()
316   {
317       boolean flag = startWrite();
318       if(!flag)
319           waitingWriters_++;
320       return flag;
321   }
322
323   protected synchronized boolean startReadFromWaitingReader()
324   {
325       boolean flag = startRead();
326       if(flag)
327               waitingReaders_--;
328          
329       return flag;
330   }
331
332   protected synchronized boolean startWriteFromWaitingWriter()
333   {
334       boolean flag = startWrite();
335       if(flag){
336           waitingWriters_--;
337       }
338       return flag;
339   }
340
341   protected synchronized Signaller endRead()
342   {
343      --activeReaders_;
344     
345     
346 // these are the changes so the readers and writers form two groups
347
if(waitingWriters_ > 0L){
348
349          return writerLock_;
350      }
351      if(waitingReaders_ > 0L){
352
353          return readerLock_;
354      }
355      else
356          return null;
357   }
358
359   protected synchronized Signaller endWrite()
360   {
361       --activeWriters_;
362
363       if(waitingReaders_ > 0L )
364       {
365           return readerLock_;
366       }
367       if(waitingWriters_ > 0L){
368          return writerLock_;
369      }
370       else
371           return null;
372   }
373
374   protected long activeReaders_;
375   protected long activeWriters_;
376   protected long waitingReaders_;
377   protected long waitingWriters_;
378   protected final ReaderLock readerLock_ = new ReaderLock();
379   protected final WriterLock writerLock_ = new WriterLock();
380 }
381
Popular Tags