samples/deadlock/src/org/apidesign/javamonitorflaws/Cache.java
author Jaroslav Tulach <jtulach@netbeans.org>
Wed, 11 Feb 2009 08:52:00 +0100
changeset 317 e101649dbd17
parent 316 41a4abecb600
permissions -rw-r--r--
Marking code snippets for the "Java Monitor" wiki page
jtulach@315
     1
package org.apidesign.javamonitorflaws;
jtulach@315
     2
jtulach@315
     3
import java.util.HashMap;
jtulach@315
     4
import java.util.Map;
jtulach@315
     5
jtulach@316
     6
/** Classical caching support class that makes sure there is
jtulach@316
     7
 * always one "To" value for each "From" one returned from the {@link #get}
jtulach@316
     8
 * method. However it does not prevent multiple threads to call
jtulach@316
     9
 * {@link #createItem} multiple times for the same "From" value.
jtulach@316
    10
 * <p>
jtulach@316
    11
 *
jtulach@315
    12
 *
jtulach@315
    13
 * @author Jaroslav Tulach <jtulach@netbeans.org>
jtulach@315
    14
 */
jtulach@317
    15
// BEGIN: monitor.pitfalls.Cache
jtulach@315
    16
public abstract class Cache<From,To> {
jtulach@315
    17
    private Map<From,To> cache;
jtulach@315
    18
jtulach@316
    19
    protected abstract To createItem(From f);
jtulach@316
    20
jtulach@315
    21
    public final To get(From f) {
jtulach@316
    22
        To t = inspectValue(f);
jtulach@316
    23
        if (t != null) {
jtulach@316
    24
            return t;
jtulach@316
    25
        }
jtulach@316
    26
        To newT = createItem(f);
jtulach@316
    27
        return registerValue(f, newT);
jtulach@316
    28
    }
jtulach@315
    29
jtulach@315
    30
jtulach@316
    31
    private synchronized To inspectValue(From f) {
jtulach@316
    32
        if (cache == null) {
jtulach@316
    33
            cache = new HashMap<From, To>();
jtulach@316
    34
        }
jtulach@316
    35
        return cache.get(f);
jtulach@316
    36
    }
jtulach@316
    37
jtulach@316
    38
    private synchronized To registerValue(From f, To newT) {
jtulach@316
    39
        To t = cache.get(f);
jtulach@316
    40
        if (t == null) {
jtulach@316
    41
            cache.put(f, newT);
jtulach@316
    42
            return newT;
jtulach@316
    43
        } else {
jtulach@316
    44
            return t;
jtulach@315
    45
        }
jtulach@315
    46
    }
jtulach@315
    47
}
jtulach@317
    48
// END: monitor.pitfalls.Cache