samples/deadlock/src/org/apidesign/javamonitorflaws/CacheOK.java
author Jaroslav Tulach <jaroslav.tulach@apidesign.org>
Thu, 30 Oct 2014 21:30:10 +0100
changeset 409 40cabcdcd2be
parent 319 6c1d8b5553d8
permissions -rw-r--r--
Updating to NBMs from NetBeans 8.0.1 as some of them are required to run on JDK8
jtulach@319
     1
package org.apidesign.javamonitorflaws;
jtulach@319
     2
jtulach@319
     3
import java.util.HashMap;
jtulach@319
     4
import java.util.Map;
jtulach@319
     5
jtulach@319
     6
/** Classical caching support class that makes sure there is
jtulach@319
     7
 * always one "To" value for each "From" one returned from the {@link #get}
jtulach@319
     8
 * method. However it does not prevent multiple threads to call
jtulach@319
     9
 * {@link #createItem} multiple times for the same "From" value.
jtulach@319
    10
 * <p>
jtulach@319
    11
 * In contrast to {@link Cache}, this is correctly synchronized.
jtulach@319
    12
 *
jtulach@319
    13
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jtulach@319
    14
 */
jtulach@319
    15
// BEGIN: monitor.pitfalls.CacheOK
jtulach@319
    16
public abstract class CacheOK<From,To> {
jtulach@320
    17
    private final Object LOCK = new Object();
jtulach@319
    18
jtulach@319
    19
    private Map<From,To> cache;
jtulach@319
    20
jtulach@319
    21
    protected abstract To createItem(From f);
jtulach@319
    22
jtulach@319
    23
    public final To get(From f) {
jtulach@319
    24
        To t = inspectValue(f);
jtulach@319
    25
        if (t != null) {
jtulach@319
    26
            return t;
jtulach@319
    27
        }
jtulach@319
    28
        To newT = createItem(f);
jtulach@319
    29
        return registerValue(f, newT);
jtulach@319
    30
    }
jtulach@319
    31
jtulach@319
    32
jtulach@319
    33
    private To inspectValue(From f) {
jtulach@319
    34
        synchronized (LOCK) {
jtulach@319
    35
            if (cache == null) {
jtulach@319
    36
                cache = new HashMap<From, To>();
jtulach@319
    37
            }
jtulach@319
    38
            return cache.get(f);
jtulach@319
    39
        }
jtulach@319
    40
    }
jtulach@319
    41
jtulach@319
    42
    private To registerValue(From f, To newT) {
jtulach@319
    43
        synchronized (LOCK) {
jtulach@319
    44
            To t = cache.get(f);
jtulach@319
    45
            if (t == null) {
jtulach@319
    46
                cache.put(f, newT);
jtulach@319
    47
                return newT;
jtulach@319
    48
            } else {
jtulach@319
    49
                return t;
jtulach@319
    50
            }
jtulach@319
    51
        }
jtulach@319
    52
    }
jtulach@319
    53
}
jtulach@319
    54
// END: monitor.pitfalls.CacheOK