Rewritten to rely on (private) synchronized methods
authorJaroslav Tulach <jtulach@netbeans.org>
Wed, 11 Feb 2009 07:12:41 +0100
changeset 31641a4abecb600
parent 315 08dd52950883
child 317 e101649dbd17
Rewritten to rely on (private) synchronized methods
samples/deadlock/src/org/apidesign/javamonitorflaws/Cache.java
samples/deadlock/test/org/apidesign/javamonitorflaws/MultiplyCache.java
     1.1 --- a/samples/deadlock/src/org/apidesign/javamonitorflaws/Cache.java	Tue Feb 10 18:36:21 2009 +0100
     1.2 +++ b/samples/deadlock/src/org/apidesign/javamonitorflaws/Cache.java	Wed Feb 11 07:12:41 2009 +0100
     1.3 @@ -3,38 +3,44 @@
     1.4  import java.util.HashMap;
     1.5  import java.util.Map;
     1.6  
     1.7 -/**
     1.8 +/** Classical caching support class that makes sure there is
     1.9 + * always one "To" value for each "From" one returned from the {@link #get}
    1.10 + * method. However it does not prevent multiple threads to call
    1.11 + * {@link #createItem} multiple times for the same "From" value.
    1.12 + * <p>
    1.13 + *
    1.14   *
    1.15   * @author Jaroslav Tulach <jtulach@netbeans.org>
    1.16   */
    1.17  public abstract class Cache<From,To> {
    1.18      private Map<From,To> cache;
    1.19  
    1.20 +    protected abstract To createItem(From f);
    1.21 +
    1.22      public final To get(From f) {
    1.23 -        for (;;) {
    1.24 -            synchronized (this) {
    1.25 -                if (cache == null) {
    1.26 -                    cache = new HashMap<From, To>();
    1.27 -                }
    1.28 -                To t = cache.get(f);
    1.29 -                if (t != null) {
    1.30 -                    return t;
    1.31 -                }
    1.32 -            }
    1.33 +        To t = inspectValue(f);
    1.34 +        if (t != null) {
    1.35 +            return t;
    1.36 +        }
    1.37 +        To newT = createItem(f);
    1.38 +        return registerValue(f, newT);
    1.39 +    }
    1.40  
    1.41 -            To newT = createItem(f);
    1.42  
    1.43 -            synchronized (this) {
    1.44 -                To t = cache.get(f);
    1.45 -                if (t == null) {
    1.46 -                    cache.put(f, newT);
    1.47 -                    return newT;
    1.48 -                } else {
    1.49 -                    return t;
    1.50 -                }
    1.51 -            }
    1.52 +    private synchronized To inspectValue(From f) {
    1.53 +        if (cache == null) {
    1.54 +            cache = new HashMap<From, To>();
    1.55 +        }
    1.56 +        return cache.get(f);
    1.57 +    }
    1.58 +
    1.59 +    private synchronized To registerValue(From f, To newT) {
    1.60 +        To t = cache.get(f);
    1.61 +        if (t == null) {
    1.62 +            cache.put(f, newT);
    1.63 +            return newT;
    1.64 +        } else {
    1.65 +            return t;
    1.66          }
    1.67      }
    1.68 -
    1.69 -    protected abstract To createItem(From f);
    1.70  }
     2.1 --- a/samples/deadlock/test/org/apidesign/javamonitorflaws/MultiplyCache.java	Tue Feb 10 18:36:21 2009 +0100
     2.2 +++ b/samples/deadlock/test/org/apidesign/javamonitorflaws/MultiplyCache.java	Wed Feb 11 07:12:41 2009 +0100
     2.3 @@ -28,7 +28,7 @@
     2.4          }
     2.5          pcs.addPropertyChangeListener(listener);
     2.6      }
     2.7 -    public void removePropertyChangeListener(PropertyChangeListener listener) {
     2.8 +    public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
     2.9          if (pcs != null) {
    2.10              pcs.removePropertyChangeListener(listener);
    2.11          }