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-- |
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 |