1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/samples/deadlock/src/org/apidesign/javamonitorflaws/CacheOK.java Thu Feb 12 10:55:02 2009 +0100
1.3 @@ -0,0 +1,54 @@
1.4 +package org.apidesign.javamonitorflaws;
1.5 +
1.6 +import java.util.HashMap;
1.7 +import java.util.Map;
1.8 +
1.9 +/** Classical caching support class that makes sure there is
1.10 + * always one "To" value for each "From" one returned from the {@link #get}
1.11 + * method. However it does not prevent multiple threads to call
1.12 + * {@link #createItem} multiple times for the same "From" value.
1.13 + * <p>
1.14 + * In contrast to {@link Cache}, this is correctly synchronized.
1.15 + *
1.16 + * @author Jaroslav Tulach <jtulach@netbeans.org>
1.17 + */
1.18 +// BEGIN: monitor.pitfalls.CacheOK
1.19 +public abstract class CacheOK<From,To> {
1.20 + private Object LOCK = new Object();
1.21 +
1.22 + private Map<From,To> cache;
1.23 +
1.24 + protected abstract To createItem(From f);
1.25 +
1.26 + public final To get(From f) {
1.27 + To t = inspectValue(f);
1.28 + if (t != null) {
1.29 + return t;
1.30 + }
1.31 + To newT = createItem(f);
1.32 + return registerValue(f, newT);
1.33 + }
1.34 +
1.35 +
1.36 + private To inspectValue(From f) {
1.37 + synchronized (LOCK) {
1.38 + if (cache == null) {
1.39 + cache = new HashMap<From, To>();
1.40 + }
1.41 + return cache.get(f);
1.42 + }
1.43 + }
1.44 +
1.45 + private To registerValue(From f, To newT) {
1.46 + synchronized (LOCK) {
1.47 + To t = cache.get(f);
1.48 + if (t == null) {
1.49 + cache.put(f, newT);
1.50 + return newT;
1.51 + } else {
1.52 + return t;
1.53 + }
1.54 + }
1.55 + }
1.56 +}
1.57 +// END: monitor.pitfalls.CacheOK