samples/deadlock/src/org/apidesign/javamonitorflaws/CacheOK.java
changeset 319 6c1d8b5553d8
child 320 9ad0cc253aa9
     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