00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 package org.objectweb.cjdbc.common.util;
00026
00027 import java.util.ArrayList;
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 public class ReadPrioritaryFIFOWriteLock
00045 {
00046
00047 private int activeReaders;
00048
00049
00050 private boolean activeWriter;
00051
00052
00053 private int waitingReaders;
00054
00055
00056 private int waitingWriters;
00057
00058 private Object readSync;
00059 private ArrayList writeWaitingQueue;
00060
00061
00062
00063
00064 public ReadPrioritaryFIFOWriteLock()
00065 {
00066 activeReaders = 0;
00067 activeWriter = false;
00068 waitingReaders = 0;
00069 waitingWriters = 0;
00070 readSync = new Object();
00071 writeWaitingQueue = new ArrayList();
00072 }
00073
00074
00075
00076
00077
00078
00079
00080 public void acquireRead() throws InterruptedException
00081 {
00082 synchronized (this)
00083 {
00084 if ((waitingWriters == 0) && !activeWriter)
00085 {
00086 activeReaders++;
00087 return;
00088 }
00089 }
00090
00091
00092 synchronized (readSync)
00093 {
00094
00095
00096
00097
00098 synchronized (this)
00099 {
00100 if (!activeWriter)
00101 {
00102 activeReaders++;
00103 return;
00104 }
00105 }
00106
00107 waitingReaders++;
00108 try
00109 {
00110 readSync.wait();
00111 }
00112 catch (InterruptedException ie)
00113 {
00114 waitingReaders--;
00115 throw ie;
00116 }
00117 waitingReaders--;
00118 }
00119 synchronized (this)
00120 {
00121 activeReaders++;
00122 }
00123 }
00124
00125
00126
00127
00128 public synchronized void releaseRead()
00129 {
00130 activeReaders--;
00131 if ((activeReaders == 0) && (waitingWriters > 0))
00132 {
00133 Object thread = writeWaitingQueue.remove(0);
00134 synchronized (thread)
00135 {
00136 thread.notify();
00137 activeWriter = true;
00138 waitingWriters--;
00139 }
00140 }
00141 }
00142
00143
00144
00145
00146
00147
00148
00149 public void acquireWrite() throws InterruptedException
00150 {
00151 synchronized (Thread.currentThread())
00152 {
00153 synchronized (this)
00154 {
00155 if ((activeReaders == 0) && !activeWriter)
00156 {
00157 activeWriter = true;
00158 return;
00159 }
00160 else
00161 {
00162 waitingWriters++;
00163 writeWaitingQueue.add(Thread.currentThread());
00164 }
00165 }
00166 try
00167 {
00168 Thread.currentThread().wait();
00169 }
00170 catch (InterruptedException ie)
00171 {
00172 releaseWrite();
00173 throw ie;
00174 }
00175 }
00176 }
00177
00178
00179
00180
00181 public synchronized void releaseWrite()
00182 {
00183 activeWriter = false;
00184
00185
00186 if (waitingWriters > 0)
00187 {
00188 Object thread = writeWaitingQueue.remove(0);
00189 synchronized (thread)
00190 {
00191 thread.notify();
00192 activeWriter = true;
00193 waitingWriters--;
00194 }
00195 }
00196
00197
00198 else
00199 synchronized (readSync)
00200 {
00201 if (waitingReaders > 0)
00202 readSync.notifyAll();
00203 }
00204 }
00205
00206
00207
00208
00209
00210
00211 public final synchronized boolean isReadLocked()
00212 {
00213 return activeReaders > 0;
00214 }
00215
00216
00217
00218
00219
00220
00221 public final synchronized boolean isWriteLocked()
00222 {
00223 return activeWriter;
00224 }
00225 }