Code - Class EDU.oswego.cs.dl.util.concurrent.SyncMap


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
308

Java API By Example, From Geeks To Geeks. | Conditions of Use | About Us © 2002 - 2005, KickJava.com, or its affiliates