KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jfree > threads > ReaderWriterLock


1 /* ========================================================================
2  * JCommon : a free general purpose class library for the Java(tm) platform
3  * ========================================================================
4  *
5  * (C) Copyright 2000-2005, by Object Refinery Limited and Contributors.
6  *
7  * Project Info: http://www.jfree.org/jcommon/index.html
8  *
9  * This library is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 of the License, or
12  * (at your option) any later version.
13  *
14  * This library is distributed in the hope that it will be useful, but
15  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16  * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17  * License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with this library; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
22  * USA.
23  *
24  * [Java is a trademark or registered trademark of Sun Microsystems, Inc.
25  * in the United States and other countries.]
26  *
27  * ---------------------
28  * ReaderWriterLock.java
29  * ---------------------
30  *
31  * $Id: ReaderWriterLock.java,v 1.3 2005/10/18 13:18:34 mungady Exp $
32  *
33  * Changes
34  * -------
35  * 29-Jan-2003 : Added standard header (DG);
36  *
37  */

38
39 package org.jfree.threads;
40
41 import java.util.ArrayList JavaDoc;
42 import java.util.Iterator JavaDoc;
43
44 /**
45  * A reader-writer lock from "Java Threads" by Scott Oak and Henry Wong.
46  *
47  * @author Scott Oak and Henry Wong
48  */

49 public class ReaderWriterLock {
50
51     /**
52      * A node for the waiting list.
53      *
54      * @author Scott Oak and Henry Wong
55      */

56     private static class ReaderWriterNode {
57
58         /** A reader. */
59         protected static final int READER = 0;
60
61         /** A writer. */
62         protected static final int WRITER = 1;
63
64         /** The thread. */
65         protected Thread JavaDoc t;
66
67         /** The state. */
68         protected int state;
69
70         /** The number of acquires.*/
71         protected int nAcquires;
72
73         /**
74          * Creates a new node.
75          *
76          * @param t the thread.
77          * @param state the state.
78          */

79         private ReaderWriterNode(final Thread JavaDoc t, final int state) {
80             this.t = t;
81             this.state = state;
82             this.nAcquires = 0;
83         }
84
85     }
86
87     /** The waiting threads. */
88     private ArrayList JavaDoc waiters;
89
90     /**
91      * Default constructor.
92      */

93     public ReaderWriterLock() {
94         this.waiters = new ArrayList JavaDoc();
95     }
96
97     /**
98      * Grab the read lock.
99      */

100     public synchronized void lockRead() {
101         final ReaderWriterNode node;
102         final Thread JavaDoc 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 JavaDoc e) {
116                 System.err.println("ReaderWriterLock.lockRead(): exception.");
117                 System.err.print(e.getMessage());
118             }
119         }
120         node.nAcquires++;
121     }
122
123     /**
124      * Grab the write lock.
125      */

126     public synchronized void lockWrite() {
127         final ReaderWriterNode node;
128         final Thread JavaDoc 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 JavaDoc("Upgrade lock");
138             }
139             node.state = ReaderWriterNode.WRITER;
140         }
141         while (getIndex(me) != 0) {
142             try {
143                 wait();
144             }
145             catch (Exception JavaDoc e) {
146                 System.err.println("ReaderWriterLock.lockWrite(): exception.");
147                 System.err.print(e.getMessage());
148             }
149         }
150         node.nAcquires++;
151     }
152
153     /**
154      * Unlock.
155      */

156     public synchronized void unlock() {
157
158         final ReaderWriterNode node;
159         final Thread JavaDoc me = Thread.currentThread();
160         final int index = getIndex(me);
161         if (index > firstWriter()) {
162             throw new IllegalArgumentException JavaDoc("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     /**
173      * Returns the index of the first waiting writer.
174      *
175      * @return The index.
176      */

177     private int firstWriter() {
178         final Iterator JavaDoc 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     /**
191      * Returns the index of a thread.
192      *
193      * @param t the thread.
194      *
195      * @return The index.
196      */

197     private int getIndex(final Thread JavaDoc t) {
198         final Iterator JavaDoc 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 }
211
Popular Tags