comparison src/EDU/oswego/cs/dl/util/concurrent/SyncMap.java @ 0:3dc0c5604566

Initial checkin of blitz 2.0 fcs - no installer yet.
author Dan Creswell <dan.creswell@gmail.com>
date Sat, 21 Mar 2009 11:00:06 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 /*
2 File: SyncMap.java
3
4 Originally written by Doug Lea and released into the public domain.
5 This may be used for any purposes whatsoever without acknowledgment.
6 Thanks for the assistance and support of Sun Microsystems Labs,
7 and everyone contributing, testing, and using this code.
8
9 History:
10 Date Who What
11 1Aug1998 dl Create public version
12 */
13
14 package EDU.oswego.cs.dl.util.concurrent;
15 import java.util.*;
16
17 /**
18 * SyncMaps wrap Sync-based control around java.util.Maps.
19 * They operate in the same way as SyncCollection.
20 * <p>
21 * Reader operations are
22 * <ul>
23 * <li> size
24 * <li> isEmpty
25 * <li> get
26 * <li> containsKey
27 * <li> containsValue
28 * <li> keySet
29 * <li> entrySet
30 * <li> values
31 * </ul>
32 * Writer operations are:
33 * <ul>
34 * <li> put
35 * <li> putAll
36 * <li> remove
37 * <li> clear
38 * </ul>
39 *
40 * <p>[<a href="http://gee.cs.oswego.edu/dl/classes/EDU/oswego/cs/dl/util/concurrent/intro.html"> Introduction to this package. </a>]
41 * @see SyncCollection
42 **/
43
44
45 public class SyncMap implements Map {
46 protected final Map c_; // Backing Map
47 protected final Sync rd_; // sync for read-only methods
48 protected final Sync wr_; // sync for mutative methods
49
50 protected final SynchronizedLong syncFailures_ = new SynchronizedLong(0);
51
52 /**
53 * Create a new SyncMap protecting the given map,
54 * and using the given sync to control both reader and writer methods.
55 * Common, reasonable choices for the sync argument include
56 * Mutex, ReentrantLock, and Semaphores initialized to 1.
57 **/
58 public SyncMap(Map map, Sync sync) {
59 this (map, sync, sync);
60 }
61
62
63 /**
64 * Create a new SyncMap protecting the given map,
65 * and using the given ReadWriteLock to control reader and writer methods.
66 **/
67 public SyncMap(Map map, ReadWriteLock rwl) {
68 this (map, rwl.readLock(), rwl.writeLock());
69 }
70
71 /**
72 * Create a new SyncMap protecting the given map,
73 * and using the given pair of locks to control reader and writer methods.
74 **/
75 public SyncMap(Map map, Sync readLock, Sync writeLock) {
76 c_ = map;
77 rd_ = readLock;
78 wr_ = writeLock;
79 }
80
81 /**
82 * Return the Sync object managing read-only operations
83 **/
84
85 public Sync readerSync() {
86 return rd_;
87 }
88
89 /**
90 * Return the Sync object managing mutative operations
91 **/
92
93 public Sync writerSync() {
94 return wr_;
95 }
96
97 /**
98 * Return the number of synchronization failures for read-only operations
99 **/
100 public long syncFailures() {
101 return syncFailures_.get();
102 }
103
104
105 /** Try to acquire sync before a reader operation; record failure **/
106 protected boolean beforeRead() {
107 try {
108 rd_.acquire();
109 return false;
110 }
111 catch (InterruptedException ex) {
112 syncFailures_.increment();
113 return true;
114 }
115 }
116
117 /** Clean up after a reader operation **/
118 protected void afterRead(boolean wasInterrupted) {
119 if (wasInterrupted) {
120 Thread.currentThread().interrupt();
121 }
122 else
123 rd_.release();
124 }
125
126
127
128 public int hashCode() {
129 boolean wasInterrupted = beforeRead();
130 try {
131 return c_.hashCode();
132 }
133 finally {
134 afterRead(wasInterrupted);
135 }
136 }
137
138 public boolean equals(Object o) {
139 boolean wasInterrupted = beforeRead();
140 try {
141 return c_.equals(o);
142 }
143 finally {
144 afterRead(wasInterrupted);
145 }
146 }
147
148 public int size() {
149 boolean wasInterrupted = beforeRead();
150 try {
151 return c_.size();
152 }
153 finally {
154 afterRead(wasInterrupted);
155 }
156 }
157
158 public boolean isEmpty() {
159 boolean wasInterrupted = beforeRead();
160 try {
161 return c_.isEmpty();
162 }
163 finally {
164 afterRead(wasInterrupted);
165 }
166 }
167
168 public boolean containsKey(Object o) {
169 boolean wasInterrupted = beforeRead();
170 try {
171 return c_.containsKey(o);
172 }
173 finally {
174 afterRead(wasInterrupted);
175 }
176 }
177
178 public boolean containsValue(Object o) {
179 boolean wasInterrupted = beforeRead();
180 try {
181 return c_.containsValue(o);
182 }
183 finally {
184 afterRead(wasInterrupted);
185 }
186 }
187
188 public Object get(Object key) {
189 boolean wasInterrupted = beforeRead();
190 try {
191 return c_.get(key);
192 }
193 finally {
194 afterRead(wasInterrupted);
195 }
196 }
197
198
199 public Object put(Object key, Object value) {
200 try {
201 wr_.acquire();
202 try {
203 return c_.put(key, value);
204 }
205 finally {
206 wr_.release();
207 }
208 }
209 catch (InterruptedException ex) {
210 Thread.currentThread().interrupt();
211 throw new UnsupportedOperationException();
212 }
213 }
214
215 public Object remove(Object key) {
216 try {
217 wr_.acquire();
218 try {
219 return c_.remove(key);
220 }
221 finally {
222 wr_.release();
223 }
224 }
225 catch (InterruptedException ex) {
226 Thread.currentThread().interrupt();
227 throw new UnsupportedOperationException();
228 }
229 }
230
231 public void putAll(Map coll) {
232 try {
233 wr_.acquire();
234 try {
235 c_.putAll(coll);
236 }
237 finally {
238 wr_.release();
239 }
240 }
241 catch (InterruptedException ex) {
242 Thread.currentThread().interrupt();
243 throw new UnsupportedOperationException();
244 }
245 }
246
247
248 public void clear() {
249 try {
250 wr_.acquire();
251 try {
252 c_.clear();
253 }
254 finally {
255 wr_.release();
256 }
257 }
258 catch (InterruptedException ex) {
259 Thread.currentThread().interrupt();
260 throw new UnsupportedOperationException();
261 }
262 }
263
264 private transient Set keySet_ = null;
265 private transient Set entrySet_ = null;
266 private transient Collection values_ = null;
267
268 public Set keySet() {
269 boolean wasInterrupted = beforeRead();
270 try {
271 if (keySet_ == null)
272 keySet_ = new SyncSet(c_.keySet(), rd_, wr_);
273 return keySet_;
274 }
275 finally {
276 afterRead(wasInterrupted);
277 }
278 }
279
280 public Set entrySet() {
281 boolean wasInterrupted = beforeRead();
282 try {
283 if (entrySet_ == null)
284 entrySet_ = new SyncSet(c_.entrySet(), rd_, wr_);
285 return entrySet_;
286 }
287 finally {
288 afterRead(wasInterrupted);
289 }
290 }
291
292
293 public Collection values() {
294 boolean wasInterrupted = beforeRead();
295 try {
296 if (values_ == null)
297 values_ = new SyncCollection(c_.values(), rd_, wr_);
298 return values_;
299 }
300 finally {
301 afterRead(wasInterrupted);
302 }
303 }
304
305 }
306
307