KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > enterprise > util > sync > RWLock


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24 //NOTE: Tabs are used instead of spaces for indentation.
25
// Make sure that your editor does not replace tabs with spaces.
26
// Set the tab length using your favourite editor to your
27
// visual preference.
28

29 /*
30  * Filename: Lock.java
31  *
32  * Copyright 2000-2001 by iPlanet/Sun Microsystems, Inc.,
33  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
34  * All rights reserved.
35  *
36  * This software is the confidential and proprietary information
37  * of iPlanet/Sun Microsystems, Inc. ("Confidential Information").
38  * You shall not disclose such Confidential Information and shall
39  * use it only in accordance with the terms of the license
40  * agreement you entered into with iPlanet/Sun Microsystems.
41  */

42  
43 /**
44  * <BR> <I>$Source: /cvs/glassfish/appserv-commons/src/java/com/sun/enterprise/util/sync/RWLock.java,v $</I>
45  * @author $Author: tcfujii $
46  * @version $Revision: 1.3 $ $Date: 2005/12/25 04:12:31 $
47  */

48  
49
50 package com.sun.enterprise.util.sync;
51
52 import java.lang.InterruptedException JavaDoc;
53 import java.util.LinkedList JavaDoc;
54 //Bug 4677074 begin
55
import java.util.logging.Logger JavaDoc;
56 import java.util.logging.Level JavaDoc;
57 import com.sun.logging.LogDomains;
58 //Bug 4677074 end
59

60 /**
61  * A <i>RWLock</i> provides concurrency control for multiple readers single writer
62  * access patterns. This lock can provide access to multiple reader threads simultaneously
63  * as long as there are no writer threads. Once a writer thread gains access to the
64  * instance locked by a RWLock, all the reader threads wait till the writer completes
65  * accessing the instance in question.
66  * <p>
67  * A RWLock is extremely useful in scenarios where there are lots more readers and
68  * very few writers to a data structure. Also if the read operation by the reader
69  * thread could take significant amount of time (binary search etc.)
70  * <p>
71  * The usage of Lock can be see as under:
72  * <p><hr><blockquote><pre>
73  * public class MyBTree {
74  * private RWLock lock = new Lock();
75  * .....
76  * .....
77  * public Object find(Object o) {
78  * try {
79  * lock.acquireReadLock();
80  * ....perform complex search to get the Object ...
81  * return result;
82  * } finally {
83  * lock.releaseReadLock();
84  * }
85  * }
86  *
87  * public void insert(Object o) {
88  * try {
89  * lock.acquireWriteLock();
90  * ....perform complex operation to insert object ...
91  * } finally {
92  * lock.releaseWriteLock();
93  * }
94  * }
95  * }
96  * </pre></blockquote><hr>
97  * <p>
98  * @author Dhiru Pandey 8/7/2000
99  */

100
101
102 public class RWLock {
103
104 //Bug 4677074 begin
105
static Logger JavaDoc _logger=LogDomains.getLogger(LogDomains.UTIL_LOGGER);
106 //Bug 4677074 end
107
int currentReaders;
108   int pendingReaders;
109   int currentWriters;
110   Queue writerQueue = new Queue();
111
112   /**
113    * This method is used to acquire a read lock. If there is already a writer thread
114    * accessing the object using the RWLock then the reader thread will wait until
115    * the writer completes its operation
116    */

117   public synchronized void acquireReadLock() {
118     if (currentWriters == 0 && writerQueue.size() == 0) {
119       ++currentReaders;
120     } else {
121       ++pendingReaders;
122       try {
123         wait();
124       } catch(InterruptedException JavaDoc ie) {
125       }
126     }
127   }
128
129   /**
130    * This method is used to acquire a write lock. If there are already reader threads
131    * accessing the object using the RWLock, then the writer thread will wait till all
132    * the reader threads are finished with their operations.
133    */

134   public void acquireWriteLock() {
135     Object JavaDoc lock = new Object JavaDoc();
136
137     synchronized(lock) {
138       synchronized(this) {
139         if (writerQueue.size() == 0 && currentReaders == 0 &&
140                                           currentWriters == 0) {
141           ++currentWriters;
142           // Use logging facility if you need to log this
143
// System.out.println(" RW: incremented WriterLock count");
144
//Bug 4677074 begin
145
_logger.log(Level.FINE," RW: incremented WriterLock count");
146 //Bug 4677074 end
147
return;
148         }
149           writerQueue.enQueue(lock);
150           // Use logging facility if you need to log this
151
// System.out.println(" RW: Added WriterLock to queue");
152
//Bug 4677074 begin
153
_logger.log(Level.FINE," RW: Added WriterLock to queue");
154 //Bug 4677074 end
155
}
156       try {
157         lock.wait();
158       } catch(InterruptedException JavaDoc ie) {
159       }
160     }
161   }
162
163   /**
164    * This method is used to release a read lock. It also notifies any waiting writer thread
165    * that it could now acquire a write lock.
166    */

167   public synchronized void releaseReadLock() {
168     if (--currentReaders == 0)
169       notifyWriters();
170   }
171
172   /**
173    * This method is used to release a write lock. It also notifies any pending
174    * readers that they could now acquire the read lock. If there are no reader
175    * threads then it will try to notify any waiting writer thread that it could now
176    * acquire a write lock.
177    */

178   public synchronized void releaseWriteLock() {
179     --currentWriters;
180     if (pendingReaders > 0)
181       notifyReaders();
182     else
183       notifyWriters();
184   }
185
186   private void notifyReaders() {
187     currentReaders += pendingReaders;
188     pendingReaders = 0;
189     notifyAll();
190   }
191   
192   private void notifyWriters() {
193     if (writerQueue.size() > 0) {
194       Object JavaDoc lock = writerQueue.deQueueFirst();
195       ++currentWriters;
196       synchronized(lock) {
197         lock.notify();
198       }
199     }
200   }
201
202   class Queue extends LinkedList JavaDoc {
203
204     public Queue() {
205       super();
206     }
207
208     public void enQueue(Object JavaDoc o) {
209       super.addLast(o);
210     }
211
212     public Object JavaDoc deQueueFirst() {
213       return super.removeFirst();
214     }
215
216   }
217
218 }
219
220
Popular Tags