# HG changeset patch # User Jaroslav Tulach # Date 1234332761 -3600 # Node ID 41a4abecb6008f97de7e4df3ae187ec97af87ee5 # Parent 08dd52950883b13f6462fd95952369f1808be81d Rewritten to rely on (private) synchronized methods diff -r 08dd52950883 -r 41a4abecb600 samples/deadlock/src/org/apidesign/javamonitorflaws/Cache.java --- a/samples/deadlock/src/org/apidesign/javamonitorflaws/Cache.java Tue Feb 10 18:36:21 2009 +0100 +++ b/samples/deadlock/src/org/apidesign/javamonitorflaws/Cache.java Wed Feb 11 07:12:41 2009 +0100 @@ -3,38 +3,44 @@ import java.util.HashMap; import java.util.Map; -/** +/** Classical caching support class that makes sure there is + * always one "To" value for each "From" one returned from the {@link #get} + * method. However it does not prevent multiple threads to call + * {@link #createItem} multiple times for the same "From" value. + *

+ * * * @author Jaroslav Tulach */ public abstract class Cache { private Map cache; + protected abstract To createItem(From f); + public final To get(From f) { - for (;;) { - synchronized (this) { - if (cache == null) { - cache = new HashMap(); - } - To t = cache.get(f); - if (t != null) { - return t; - } - } + To t = inspectValue(f); + if (t != null) { + return t; + } + To newT = createItem(f); + return registerValue(f, newT); + } - To newT = createItem(f); - synchronized (this) { - To t = cache.get(f); - if (t == null) { - cache.put(f, newT); - return newT; - } else { - return t; - } - } + private synchronized To inspectValue(From f) { + if (cache == null) { + cache = new HashMap(); + } + return cache.get(f); + } + + private synchronized To registerValue(From f, To newT) { + To t = cache.get(f); + if (t == null) { + cache.put(f, newT); + return newT; + } else { + return t; } } - - protected abstract To createItem(From f); } diff -r 08dd52950883 -r 41a4abecb600 samples/deadlock/test/org/apidesign/javamonitorflaws/MultiplyCache.java --- a/samples/deadlock/test/org/apidesign/javamonitorflaws/MultiplyCache.java Tue Feb 10 18:36:21 2009 +0100 +++ b/samples/deadlock/test/org/apidesign/javamonitorflaws/MultiplyCache.java Wed Feb 11 07:12:41 2009 +0100 @@ -28,7 +28,7 @@ } pcs.addPropertyChangeListener(listener); } - public void removePropertyChangeListener(PropertyChangeListener listener) { + public synchronized void removePropertyChangeListener(PropertyChangeListener listener) { if (pcs != null) { pcs.removePropertyChangeListener(listener); }