1:
38:
39: package ;
40:
41: import ;
42: import ;
43:
44:
49: public class ReaderWriterLock {
50:
51:
56: private static class ReaderWriterNode {
57:
58:
59: protected static final int READER = 0;
60:
61:
62: protected static final int WRITER = 1;
63:
64:
65: protected Thread t;
66:
67:
68: protected int state;
69:
70:
71: protected int nAcquires;
72:
73:
79: private ReaderWriterNode(final Thread t, final int state) {
80: this.t = t;
81: this.state = state;
82: this.nAcquires = 0;
83: }
84:
85: }
86:
87:
88: private ArrayList waiters;
89:
90:
93: public ReaderWriterLock() {
94: this.waiters = new ArrayList();
95: }
96:
97:
100: public synchronized void lockRead() {
101: final ReaderWriterNode node;
102: final Thread me = Thread.currentThread();
103: final int index = getIndex(me);
104: if (index == -1) {
105: node = new ReaderWriterNode(me, ReaderWriterNode.READER);
106: this.waiters.add(node);
107: }
108: else {
109: node = (ReaderWriterNode) this.waiters.get(index);
110: }
111: while (getIndex(me) > firstWriter()) {
112: try {
113: wait();
114: }
115: catch (Exception e) {
116: System.err.println("ReaderWriterLock.lockRead(): exception.");
117: System.err.print(e.getMessage());
118: }
119: }
120: node.nAcquires++;
121: }
122:
123:
126: public synchronized void lockWrite() {
127: final ReaderWriterNode node;
128: final Thread me = Thread.currentThread();
129: final int index = getIndex(me);
130: if (index == -1) {
131: node = new ReaderWriterNode(me, ReaderWriterNode.WRITER);
132: this.waiters.add(node);
133: }
134: else {
135: node = (ReaderWriterNode) this.waiters.get(index);
136: if (node.state == ReaderWriterNode.READER) {
137: throw new IllegalArgumentException("Upgrade lock");
138: }
139: node.state = ReaderWriterNode.WRITER;
140: }
141: while (getIndex(me) != 0) {
142: try {
143: wait();
144: }
145: catch (Exception e) {
146: System.err.println("ReaderWriterLock.lockWrite(): exception.");
147: System.err.print(e.getMessage());
148: }
149: }
150: node.nAcquires++;
151: }
152:
153:
156: public synchronized void unlock() {
157:
158: final ReaderWriterNode node;
159: final Thread me = Thread.currentThread();
160: final int index = getIndex(me);
161: if (index > firstWriter()) {
162: throw new IllegalArgumentException("Lock not held");
163: }
164: node = (ReaderWriterNode) this.waiters.get(index);
165: node.nAcquires--;
166: if (node.nAcquires == 0) {
167: this.waiters.remove(index);
168: }
169: notifyAll();
170: }
171:
172:
177: private int firstWriter() {
178: final Iterator e = this.waiters.iterator();
179: int index = 0;
180: while (e.hasNext()) {
181: final ReaderWriterNode node = (ReaderWriterNode) e.next();
182: if (node.state == ReaderWriterNode.WRITER) {
183: return index;
184: }
185: index += 1;
186: }
187: return Integer.MAX_VALUE;
188: }
189:
190:
197: private int getIndex(final Thread t) {
198: final Iterator e = this.waiters.iterator();
199: int index = 0;
200: while (e.hasNext()) {
201: final ReaderWriterNode node = (ReaderWriterNode) e.next();
202: if (node.t == t) {
203: return index;
204: }
205: index += 1;
206: }
207: return -1;
208: }
209:
210: }