KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > riotfamily > cachius > support > ReaderWriterLock


1 /* ***** BEGIN LICENSE BLOCK *****
2  * Version: MPL 1.1
3  * The contents of this file are subject to the Mozilla Public License Version
4  * 1.1 (the "License"); you may not use this file except in compliance with
5  * the License. You may obtain a copy of the License at
6  * http://www.mozilla.org/MPL/
7  *
8  * Software distributed under the License is distributed on an "AS IS" basis,
9  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
10  * for the specific language governing rights and limitations under the
11  * License.
12  *
13  * The Original Code is Riot.
14  *
15  * The Initial Developer of the Original Code is
16  * Neteye GmbH.
17  * Portions created by the Initial Developer are Copyright (C) 2006
18  * the Initial Developer. All Rights Reserved.
19  *
20  * Contributor(s):
21  * Felix Gnass [fgnass at neteye dot de]
22  *
23  * ***** END LICENSE BLOCK ***** */

24 package org.riotfamily.cachius.support;
25
26 import java.util.LinkedList JavaDoc;
27
28 /**
29  * Class implementing a reader/writer lock with FIFO ordering.
30  *
31  * @author Felix Gnass
32  */

33 public class ReaderWriterLock {
34
35     private int activeReaders;
36     private int waitingReaders;
37     private int activeWriters;
38
39     private final LinkedList JavaDoc writerLocks = new LinkedList JavaDoc();
40
41     /**
42      * Aquire a read lock. A call to this method will block until the
43      * current writer (if any) has finished.
44      */

45     public synchronized void lockForReading() {
46         if (activeWriters == 0 && writerLocks.size() == 0) {
47             ++activeReaders;
48         }
49         else {
50             ++waitingReaders;
51             try {
52                 wait();
53             }
54             catch (InterruptedException JavaDoc e) {
55             }
56         }
57     }
58
59
60     /**
61      * Request a reader lock.
62      *
63      * @return true if you can safely read from the source
64      * false otherwise
65      */

66     public synchronized boolean tryLockForReading() {
67         if (activeWriters == 0 && writerLocks.size() == 0) {
68             ++activeReaders;
69             return true;
70         }
71         return false;
72     }
73
74
75     /**
76      * Release the read lock.
77      */

78     public synchronized void releaseReaderLock() {
79         if (--activeReaders == 0) {
80             notifyFirstWriter();
81         }
82     }
83
84
85     /**
86      * Request the write lock. The call blocks until a write operation
87      * can be performed safely. Write requests are guaranteed to be executed
88      * in the order received (FIFO). Pending read requests take precedence
89      * over all write requests.
90      */

91     public void lockForWriting() {
92         Object JavaDoc lock = new Object JavaDoc();
93         synchronized (lock) {
94             synchronized (this) {
95                 boolean canWrite = writerLocks.size() == 0
96                         && activeReaders == 0 && activeWriters == 0;
97                         
98                 if (canWrite) {
99                     ++activeWriters;
100                     return;
101                 }
102                 writerLocks.addLast(lock);
103             }
104             try {
105                 lock.wait();
106             }
107             catch (InterruptedException JavaDoc e) {
108             }
109         }
110     }
111
112
113     /**
114      * Aquire a write lock (non-blocking).
115      */

116     public synchronized boolean tryLockForWriting() {
117         if (writerLocks.size() == 0 && activeReaders == 0
118                 && activeWriters == 0) {
119             
120             ++activeWriters;
121             return true;
122         }
123         return false;
124     }
125
126
127
128     /**
129      * Release the write lock.
130      */

131     public synchronized void releaseWriterLock() {
132         --activeWriters;
133         if (waitingReaders > 0) {
134             notifyReaders();
135         }
136         else {
137             notifyFirstWriter();
138         }
139     }
140
141
142     /**
143      * Notify all threads waiting for read access.
144      */

145     private void notifyReaders() {
146         activeReaders += waitingReaders;
147         waitingReaders = 0;
148         notifyAll();
149     }
150
151     /**
152      * Notify the first (oldest) writer.
153      */

154      private void notifyFirstWriter() {
155          if (writerLocks.size() > 0) {
156              Object JavaDoc oldest = writerLocks.removeFirst();
157              ++activeWriters;
158              synchronized (oldest) {
159                  oldest.notify();
160              }
161          }
162      }
163     
164 }
165
Popular Tags