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 monitor = new Object (); 11 12 private class TableLock{ 13 Object 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 owner; 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 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 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 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; 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 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 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 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 |