KickJava   Java API By Example, From Geeks To Geeks.

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


1 package com.daffodilwoods.daffodildb.server.datasystem.utility;
2
3 import java.util.*;
4
5 public class ReadWriteLocker 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     private class TableLock{
13       Object JavaDoc owner;
14       int waitingThreads=0;
15
16       synchronized void incrementWaiters(){
17         ++waitingThreads;
18       }
19
20       synchronized void decrementWaitersToZero(){
21         waitingThreads = 0;
22       }
23
24       synchronized int waitersCount(){
25         return waitingThreads;
26       }
27     }
28
29     private class RowLock{
30       Object JavaDoc owner; // initialized in case of write lock.
31
int readersCount;
32       private int waitingThreads;
33
34       synchronized void increment(){
35           ++readersCount;
36       }
37
38       synchronized void decrement(){
39           --readersCount;
40       }
41
42       synchronized int readersCount(){
43         return readersCount;
44       }
45
46       synchronized void incrementWaiters(){
47         ++waitingThreads;
48       }
49
50       synchronized void decrementWaitersToZero(){
51         waitingThreads = 0;
52       }
53
54       synchronized int waitingThreads(){
55         return waitingThreads;
56       }
57
58     }
59
60     public ReadWriteLocker() {
61     }
62
63     private void waitOnTableLock(){
64       synchronized ( tableLock ){
65         try{
66           tableLock.wait(5);
67         }catch(InterruptedException JavaDoc ie ){
68         }
69       }
70     }
71
72     private void notifyOnTableLock(){
73       synchronized (tableLock){
74           tableLock.notifyAll();
75       }
76     }
77
78     private void waitOnRowLock(RowLock rw){
79       synchronized( rw ){
80         try{
81           rw.wait(5);
82         }catch(InterruptedException JavaDoc ie ){
83         }
84       }
85     }
86
87     private void notifyOnRowLock(RowLock rw){
88       synchronized( rw ){
89           rw.notifyAll();
90       }
91     }
92
93     public void lockTable() {
94         for(;;){
95             if( tableLocked ){
96                 waitOnTableLock();
97             }
98             else if ( map.size() > 0 )
99             {
100                 tableLock.incrementWaiters();
101                 waitOnTableLock();
102             }
103             else{
104                 synchronized( monitor ){
105                     if( map.size() == 0 ){
106                         tableLocked = true;
107                         tableLock.decrementWaitersToZero();
108                         tableLock.owner = Thread.currentThread();
109                         return;
110                     }
111                 }
112             }
113         }
114     }
115
116     public void releaseTable() {
117         synchronized( monitor ) {
118           tableLock.owner = null;
119           tableLocked = false;
120
121           notifyOnTableLock();
122         }
123     }
124
125     public void lockRowForRead(Object JavaDoc rowIdentity) {
126         for(;;){
127             RowLock rw = (RowLock)map.get(rowIdentity);
128             if( rw != null ){
129                 if( rw.owner == Thread.currentThread() ){
130                     synchronized( monitor ){
131                         rw.increment();
132                         map.put(rowIdentity,rw);
133                         return;
134                     }
135                 }
136                 else if ( tableLock.waitersCount() > 0 ){
137                     waitOnTableLock();
138                 }
139                 else if( rw.owner == null && rw.waitingThreads()==0){
140                     synchronized( monitor ){
141                         if( tableLocked == false ){
142                             rw = (RowLock)map.get(rowIdentity);
143                             rw = rw == null ? new RowLock() : rw;// comment this line if any prob
144
if(rw !=null && rw.owner == null && rw.waitingThreads()==0 ){
145                                 rw.increment();
146                                 map.put(rowIdentity,rw);
147                                 return;
148                             }
149                         }
150                     }
151                 }
152                 else{
153                     rw.incrementWaiters();
154                     waitOnRowLock(rw);
155                 }
156             }
157             else if ( tableLocked ){
158                 waitOnTableLock();
159             }
160             else if ( tableLock.waitersCount() > 0 ){
161                 waitOnTableLock();
162             }
163             else{
164                 synchronized( monitor ){
165                     if( tableLocked == false ){
166                         rw = (RowLock)map.get(rowIdentity);
167                         rw = rw == null ? new RowLock() : rw;
168                         if( rw.owner == null ){
169                             rw.increment();
170                             map.put(rowIdentity,rw);
171                             return;
172                         }
173                     }
174                 }
175             }
176         }
177     }
178
179     public void releaseRowForRead(Object JavaDoc rowIdentity) {
180         synchronized(monitor){
181           RowLock rw = (RowLock) map.get(rowIdentity);
182           rw.decrement();
183
184           if( rw.readersCount() == 0 ){
185             map.remove(rowIdentity);
186
187             if ( tableLock.waitersCount() > 0 )
188               notifyOnTableLock();
189
190             if( rw.waitingThreads() > 0 )
191               notifyOnRowLock(rw);
192           }
193         }
194     }
195
196     public void lockRowForWrite(Object JavaDoc rowIdentity) {
197         for(;;){
198           RowLock rw = (RowLock) map.get(rowIdentity);
199           if( rw != null ){
200             if( tableLock.waitersCount() > 0){
201               waitOnTableLock();
202             }
203             else{
204               rw.incrementWaiters();
205               waitOnRowLock(rw);
206             }
207           }
208           else if ( tableLocked ){
209             waitOnTableLock();
210           }
211           else if ( tableLock.waitersCount() > 0 ){
212             waitOnTableLock();
213           }
214           else{
215               synchronized( monitor ){
216                   if( tableLocked == false ){
217                       rw = (RowLock) map.get(rowIdentity);
218                       rw = rw == null ? new RowLock() : rw;
219                       if( rw.readersCount() == 0 ){
220                           rw.increment();
221                           rw.owner = Thread.currentThread();
222                           map.put(rowIdentity,rw);
223                           return;
224                       }
225                   }
226               }
227           }
228         }
229     }
230
231     public void releaseRowForWrite(Object JavaDoc rowIdentity) {
232         synchronized( monitor ){
233           RowLock rw = (RowLock) map.get(rowIdentity);
234           rw.decrement();
235
236           map.remove(rowIdentity);
237
238           if( tableLock.waitersCount() > 0 ){
239             notifyOnTableLock();
240           }
241
242           if ( rw.waitingThreads() > 0 )
243             notifyOnRowLock(rw);
244         }
245     }
246
247 }
248
Popular Tags