KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > sape > carbon > core > util > thread > ReentrantWriterPreferenceReadWriteLock


1 /*
2  * The contents of this file are subject to the Sapient Public License
3  * Version 1.0 (the "License"); you may not use this file except in compliance
4  * with the License. You may obtain a copy of the License at
5  * http://carbon.sf.net/License.html.
6  *
7  * Software distributed under the License is distributed on an "AS IS" basis,
8  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9  * the specific language governing rights and limitations under the License.
10  *
11  * The Original Code is The Carbon Component Framework.
12  *
13  * The Initial Developer of the Original Code is Sapient Corporation
14  *
15  * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
16  */

17
18 package org.sape.carbon.core.util.thread;
19
20 /*
21   Originally written by Doug Lea and released into the public domain.
22   This may be used for any purposes whatsoever without acknowledgment.
23   Thanks for the assistance and support of Sun Microsystems Labs,
24   and everyone contributing, testing, and using this code.
25
26    History:
27    Date Who What
28    26 aug1998 dl Create public version
29     7 sep2000 dl Readers are now also reentrant
30    19 jan2001 dl Allow read->write upgrades if the only reader
31    10 dec2002 dl Throw IllegalStateException on extra release
32  */

33
34 import java.util.HashMap JavaDoc;
35
36 /**
37  * A writer-preference ReadWriteLock that allows both readers and
38  * writers to reacquire
39  * read or write locks in the style of a ReentrantLock.
40  * Readers are not allowed until all write locks held by
41  * the writing thread have been released.
42  * Among other applications, reentrancy can be useful when
43  * write locks are held during calls or callbacks to methods that perform
44  * reads under read locks.
45  * <p>
46  * <b>Sample usage</b>. Here is a code sketch showing how to exploit
47  * reentrancy to perform lock downgrading after updating a cache:
48  * <pre>
49  * class CachedData {
50  * Object data;
51  * volatile boolean cacheValid;
52  * ReentrantWriterPreferenceReadWriteLock rwl = ...
53  *
54  * void processCachedData() {
55  * rwl.readLock().acquire();
56  * if (!cacheValid) {
57  *
58  * // upgrade lock:
59  * rwl.readLock().release(); // must release first to obtain writelock
60  * rwl.writeLock().acquire();
61  * if (!cacheValid) { // recheck
62  * data = ...
63  * cacheValid = true;
64  * }
65  * // downgrade lock
66  * rwl.readLock().acquire(); // reacquire read without giving up lock
67  * rwl.writeLock().release(); // release write, still hold read
68  * }
69  *
70  * use(data);
71  * rwl.readLock().release();
72  * }
73  * }
74  * </pre>
75  *
76  *
77  * <p>[<a HREF="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
78  *
79  * @since carbon 2.0
80  * @author Doug Lea
81  * @version $Revision: 1.3 $($Author: dvoet $ / $Date: 2003/05/05 21:21:24 $)
82  **/

83 public class ReentrantWriterPreferenceReadWriteLock extends WriterPreferenceReadWriteLock {
84
85   /** Number of acquires on write lock by activeWriter_ thread **/
86   protected long writeHolds_ = 0;
87
88   /** Number of acquires on read lock by any reader thread **/
89   protected HashMap JavaDoc readers_ = new HashMap JavaDoc();
90
91   /** cache/reuse the special Integer value one to speed up readlocks **/
92   protected static final Integer JavaDoc IONE = new Integer JavaDoc(1);
93
94
95   protected boolean allowReader() {
96     return (activeWriter_ == null && waitingWriters_ == 0) ||
97       activeWriter_ == Thread.currentThread();
98   }
99
100   protected synchronized boolean startRead() {
101     Thread JavaDoc t = Thread.currentThread();
102     Object JavaDoc c = readers_.get(t);
103     if (c != null) { // already held -- just increment hold count
104
readers_.put(t, new Integer JavaDoc(((Integer JavaDoc)(c)).intValue()+1));
105       ++activeReaders_;
106       return true;
107     }
108     else if (allowReader()) {
109       readers_.put(t, IONE);
110       ++activeReaders_;
111       return true;
112     }
113     else
114       return false;
115   }
116
117   protected synchronized boolean startWrite() {
118     if (activeWriter_ == Thread.currentThread()) { // already held; re-acquire
119
++writeHolds_;
120       return true;
121     }
122     else if (writeHolds_ == 0) {
123       if (activeReaders_ == 0 ||
124           (readers_.size() == 1 &&
125            readers_.get(Thread.currentThread()) != null)) {
126         activeWriter_ = Thread.currentThread();
127         writeHolds_ = 1;
128         return true;
129       }
130       else
131         return false;
132     }
133     else
134       return false;
135   }
136
137
138   protected synchronized Signaller endRead() {
139     Thread JavaDoc t = Thread.currentThread();
140     Object JavaDoc c = readers_.get(t);
141     if (c == null)
142       throw new IllegalStateException JavaDoc();
143     --activeReaders_;
144     if (c != IONE) { // more than one hold; decrement count
145
int h = ((Integer JavaDoc)(c)).intValue()-1;
146       Integer JavaDoc ih = (h == 1)? IONE : new Integer JavaDoc(h);
147       readers_.put(t, ih);
148       return null;
149     }
150     else {
151       readers_.remove(t);
152
153       if (writeHolds_ > 0) // a write lock is still held by current thread
154
return null;
155       else if (activeReaders_ == 0 && waitingWriters_ > 0)
156         return writerLock_;
157       else
158         return null;
159     }
160   }
161
162   protected synchronized Signaller endWrite() {
163     --writeHolds_;
164     if (writeHolds_ > 0) // still being held
165
return null;
166     else {
167       activeWriter_ = null;
168       if (waitingReaders_ > 0 && allowReader())
169         return readerLock_;
170       else if (waitingWriters_ > 0)
171         return writerLock_;
172       else
173         return null;
174     }
175   }
176
177 }
178
179
Popular Tags