Mercurial > hg > blitz_condensed
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 |