KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > daffodilwoods > daffodildb > server > datasystem > utility > FIFOReadWriteLocker


1 package com.daffodilwoods.daffodildb.server.datasystem.utility;
2
3 import java.util.*;
4
5 public class FIFOReadWriteLocker implements ReadWriteLock{
6
7     boolean tableLocked= false;
8     TableLock tableLock = new TableLock();
9     Map map = Collections.synchronizedMap(new HashMap());
10     Object JavaDoc monitor = new Object JavaDoc();
11
12     Vector waiters = new Vector(10);
13
14     public FIFOReadWriteLocker() {
15     }
16
17     private static class TableLock{
18       Object JavaDoc owner;
19       int waitingThreads=0;
20
21       synchronized void incrementWaiters(){
22         ++waitingThreads;
23       }
24
25       synchronized void decrementWaitersToZero(){
26         waitingThreads = 0;
27       }
28
29       synchronized int waitersCount(){
30         return waitingThreads;
31       }
32     }
33
34   static private class RowLock{
35       Object JavaDoc owner; // initialized in case of write lock.
36
int readersCount;
37       private int waitingThreads;
38
39       synchronized void increment(){
40           ++readersCount;
41       }
42
43       synchronized void decrement(){
44           --readersCount;
45       }
46
47       synchronized int readersCount(){
48         return readersCount;
49       }
50
51       synchronized void incrementWaiters(){
52         ++waitingThreads;
53       }
54
55       synchronized void decrementWaitersToZero(){
56         waitingThreads = 0;
57       }
58
59       synchronized int waitingThreads(){
60         return waitingThreads;
61       }
62
63     }
64
65     private static class Wait{
66         RowLock rw;
67         boolean read;
68         private Object JavaDoc rowIdentity;
69
70         boolean rowLock;
71
72         public synchronized void doWait(){
73             try {
74                 wait(10);
75             }catch (InterruptedException JavaDoc ex) {
76             }
77         }
78
79         public synchronized void signal(){
80             notify();
81         }
82     }
83
84     private void waitOnTableLock(boolean rowLock){
85       Wait tw = new Wait();
86       tw.rowLock = rowLock;
87       waiters.add(tw);
88       do{
89           tw.doWait();
90       }while( (tableLocked || map.size() > 0) || (waiters.indexOf(tw) != 0) );
91       waiters.remove(0);
92     }
93
94 ArrayList released = new ArrayList(10);
95
96     private void notifyOnTableLock(){
97         released.clear();
98         boolean flag = true;
99 try{
100         for (int i = 0;flag && i < waiters.size(); i++) {
101             Wait w = (Wait)waiters.get(i);
102             if( w.rw == null && w.rowLock == false ){
103                 flag = false; // encounter some table lock object;
104
if( released.size() == 0 )
105                     released.add(w);
106             }
107             else if( w.read == false )
108             {
109                 for (Iterator j = released.iterator();flag && j.hasNext(); ) {
110                     Wait item = (Wait)j.next();
111                     if ( item.rowIdentity.equals(w.rowIdentity) ){
112                         flag = false;
113                     }
114                 }
115             }
116             else{
117                 released.add(w);
118             }
119         }
120 }catch(ArrayIndexOutOfBoundsException JavaDoc ae){
121 }
122
123         for (int i = 0,length=released.size(); i < length; i++) {
124             Wait w = (Wait) released.get(i);
125             w.signal();
126         }
127         released.clear();
128     }
129
130     private void waitOnRowLock(RowLock rw, Object JavaDoc rowIdentity,boolean read){
131         Wait w = new Wait();
132         w.rw = rw;
133         w.read = read;
134         w.rowIdentity = rowIdentity;
135         waiters.add(w);
136         do{
137             w.doWait();
138         }while( tableLocked || (waiters.indexOf(w) != 0) );
139         waiters.remove(0);
140     }
141
142     private void notifyOnRowLock(RowLock rw){
143        notifyOnTableLock();
144     }
145
146     public void lockTable() {
147         for(;;){
148             if( tableLocked ){
149                 waitOnTableLock(false);
150             }
151             else if ( map.size() > 0 )
152             {
153                 tableLock.incrementWaiters();
154                 waitOnTableLock(false);
155             }
156             else{
157                 synchronized( monitor ){
158                     if( map.size() == 0 ){
159                         tableLocked = true;
160                         tableLock.decrementWaitersToZero();
161                         tableLock.owner = Thread.currentThread();
162                         return;
163                     }
164                 }
165             }
166         }
167     }
168
169     public void releaseTable() {
170         synchronized( monitor ) {
171           tableLock.owner = null;
172           notifyOnTableLock();
173           tableLocked = false;
174         }
175     }
176
177     public void lockRowForRead(Object JavaDoc rowIdentity) {
178         for(;;){
179             RowLock rw = (RowLock)map.get(rowIdentity);
180             if( rw != null ){
181                 if( rw.owner == Thread.currentThread() ){
182                     synchronized( monitor ){
183                         rw.increment();
184                         map.put(rowIdentity,rw);
185                         return;
186                     }
187                 }
188                 else if ( tableLock.waitersCount() > 0 ){
189                     waitOnTableLock(true);
190                 }
191                 else if( rw.owner == null && rw.waitingThreads()==0){
192                     synchronized( monitor ){
193                         if( tableLocked == false ){
194                             rw = (RowLock)map.get(rowIdentity);
195                             rw = rw == null ? new RowLock() : rw;// comment this line if any prob
196
if(rw !=null && rw.owner == null && rw.waitingThreads()==0 ){
197                                 rw.increment();
198                                 map.put(rowIdentity,rw);
199                                 return;
200                             }
201                         }
202                     }
203                 }
204                 else{
205                     rw.incrementWaiters();
206                     waitOnRowLock(rw,rowIdentity,true);
207                 }
208             }
209             else if ( tableLocked ){
210                 waitOnTableLock(true);
211             }
212             else if ( tableLock.waitersCount() > 0 ){
213                 waitOnTableLock(true);
214             }
215             else{
216                 synchronized( monitor ){
217                     if( tableLocked == false ){
218                         rw = (RowLock)map.get(rowIdentity);
219                         rw = rw == null ? new RowLock() : rw;
220                         if( rw.owner == null ){
221                             rw.increment();
222                             map.put(rowIdentity,rw);
223                             return;
224                         }
225                     }
226                 }
227             }
228         }
229     }
230
231     public void releaseRowForRead(Object JavaDoc rowIdentity) {
232         synchronized(monitor){
233           RowLock rw = (RowLock) map.get(rowIdentity);
234           tableLocked=true;
235           rw.decrement();
236
237           if( rw.readersCount() == 0 ){
238             map.remove(rowIdentity);
239
240             if ( tableLock.waitersCount() > 0 )
241               notifyOnTableLock();
242
243             if( rw.waitingThreads() > 0 )
244               notifyOnRowLock(rw);
245           }
246           tableLocked=false;
247         }
248     }
249
250     public void lockRowForWrite(Object JavaDoc rowIdentity) {
251         for(;;){
252           RowLock rw = (RowLock) map.get(rowIdentity);
253           if( rw != null ){
254             if( tableLock.waitersCount() > 0){
255               waitOnTableLock(true);
256             }
257             else{
258               rw.incrementWaiters();
259               waitOnRowLock(rw,rowIdentity,false);
260             }
261           }
262           else if ( tableLocked ){
263             waitOnTableLock(true);
264           }
265           else if ( tableLock.waitersCount() > 0 ){
266             waitOnTableLock(true);
267           }
268           else{
269               synchronized( monitor ){
270                   if( tableLocked == false ){
271                       rw = (RowLock) map.get(rowIdentity);
272                       rw = rw == null ? new RowLock() : rw;
273                       if( rw.readersCount() == 0 ){
274                           rw.increment();
275                           rw.owner = Thread.currentThread();
276                           map.put(rowIdentity,rw);
277                           return;
278                       }
279                   }
280               }
281           }
282         }
283     }
284
285     public void releaseRowForWrite(Object JavaDoc rowIdentity) {
286         synchronized( monitor ){
287           RowLock rw = (RowLock) map.get(rowIdentity);
288           tableLocked = true;
289           rw.decrement();
290
291           map.remove(rowIdentity);
292
293           if( tableLock.waitersCount() > 0 ){
294             notifyOnTableLock();
295           }
296
297           if ( rw.waitingThreads() > 0 )
298             notifyOnRowLock(rw);
299
300           tableLocked = false;
301         }
302     }
303 }
304
Popular Tags