1 package com.daffodilwoods.daffodildb.server.datasystem.utility; 2 3 import java.util.*; 4 5 public class SimpleFIFOReadWriteLocker implements ReadWriteLock { 6 boolean tableLocked= false; 7 Object monitor = new Object (); 8 Vector waiters = new Vector(10); 9 10 TableLock tableLock = new TableLock(); 11 RowLock rowLock = new RowLock(); 12 13 14 public SimpleFIFOReadWriteLocker() { 15 } 16 17 private class TableLock{ 18 Object 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 private class RowLock{ 35 Object owner; 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 private class Wait{ 65 boolean rowLock; 66 67 public synchronized void doWait(){ 68 try { 69 wait(5); 70 }catch (InterruptedException ex) { 71 } 72 } 73 74 public synchronized void signal(){ 75 notify(); 76 } 77 } 78 79 private void waitOnTableLock(){ 80 Wait tw = new Wait(); 81 tw.rowLock = false; 82 waiters.add(tw); 83 do{ 84 tw.doWait(); 85 }while( (tableLocked || rowLock.readersCount() > 0) || (waiters.indexOf(tw) != 0) ); 86 waiters.remove(0); 87 } 88 89 private void waitOnRowLock(){ 90 Wait tw = new Wait(); 91 tw.rowLock = true; 92 waiters.add(tw); 93 do{ 94 tw.doWait(); 95 }while( tableLocked || (waiters.indexOf(tw) != 0) ); 96 waiters.remove(0); 97 } 98 99 ArrayList notifiers = new ArrayList(); 100 101 private void notifyOnTableLock(){ 102 boolean flag = true; 103 try{ 104 for (int i = 0;flag && i < waiters.size(); i++) { 105 Wait w = (Wait)waiters.get(i); 106 if( w.rowLock == false ){ 107 flag = false; if( notifiers.size() == 0 ) 109 notifiers.add(w); 110 } 111 else{ 112 notifiers.add(w); 113 } 114 } 115 }catch(ArrayIndexOutOfBoundsException ae){ 116 } 117 for (int i = 0,size = notifiers.size(); i < size; i++) { 118 Wait w = (Wait) notifiers.get(i); 119 w.signal(); 120 } 121 notifiers.clear(); 122 } 123 124 public void lockTable() { 125 for(;;){ 126 if( tableLocked ){ 127 waitOnTableLock(); 128 } 129 else if ( rowLock.readersCount() > 0 ) 130 { 131 tableLock.incrementWaiters(); 132 waitOnTableLock(); 133 } 134 else{ 135 synchronized( monitor ){ 136 if( rowLock.readersCount() == 0 && tableLocked == false){ 137 tableLocked = true; 138 tableLock.decrementWaitersToZero(); 139 tableLock.owner = Thread.currentThread(); 140 return; 141 } 142 } 143 } 144 } 145 } 146 147 public void releaseTable() { 148 synchronized( monitor ) { 149 tableLock.owner = null; 150 notifyOnTableLock(); 151 tableLocked = false; 152 } 153 } 154 155 public void lockRowForRead(Object rowIdentity) { 156 for (; ; ) { 157 if (tableLocked) { 158 waitOnRowLock(); 159 } 160 else if (tableLock.waitersCount() > 0) { 161 waitOnRowLock(); 162 } 163 else { 164 synchronized (monitor) { 165 if (tableLocked == false) { 166 rowLock.increment(); 167 return; 168 } 169 } 170 } 171 } 172 } 173 174 public void releaseRowForRead(Object rowIdentity) { 175 synchronized(monitor){ 176 tableLocked = true; 177 rowLock.decrement(); 178 179 if (rowLock.readersCount() == 0 && tableLock.waitersCount() > 0 ) 180 notifyOnTableLock(); 181 tableLocked = false; 182 } 183 } 184 185 public void lockRowForWrite(Object rowIdentity) { 186 lockTable(); 187 } 188 189 public void releaseRowForWrite(Object rowIdentity) { 190 releaseTable(); 191 } 192 193 } 194 | Popular Tags |