Alex Ruiz tipped me off to an update to FEST, a fluent assertion library. Thanks, Alex!
Bonus questions. Everyone know this idiom:
<K, V> V get(final K key) { final V value = concurrentMap.get(key); if (null != value) return value; concurrentMap.putIfAbsent(key, factoryMethodForV()); return concurrentMap.get(key); }
Easier question: How do you support valid null
values for the concurrent map? (Hint: monads)
Harder question: Suppose factoryMethodForV()
is expensive. How do you guarantee it is only ever called once for a given key?
UPDATE: Fixed some typos.
3 comments:
I'll take a shot at the harder of the two:
public static interface ValueFactory<K, V> {
V create(K key);
}
public V get(final K key) {
final ValueHolder<K, V> newValueHolder = new ValueHolder<K, V>(key, this.valueFactory);
final ValueHolder<K, V> prevValueHolder = this.concurrentMap.putIfAbsent(key, newValueHolder);
return prevValueHolder != null ? prevValueHolder.value() : newValueHolder.value();
}
private static class ValueHolder<K, V> {
private final Object lock = new Object();
private final K key;
private final ValueFactory<K,V> valueFactory;
private V value;
private ValueHolder(final K key, final ValueFactory<K, V> valueFactory) {
this.key = key;
this.valueFactory = valueFactory;
}
private V value() {
synchronized (this.lock) {
if (this.value == null) {
this.value = this.valueFactory.create(this.key);
}
return this.value;
}
}
}
I'll take a shot at the harder of the two:
public static interface ValueFactory<K, V> {
V create(K key);
}
public V get(final K key) {
final ValueHolder<K, V> newValueHolder = new ValueHolder<K, V>(key, this.valueFactory);
final ValueHolder<K, V> prevValueHolder = this.concurrentMap.putIfAbsent(key, newValueHolder);
return prevValueHolder != null ? prevValueHolder.value() : newValueHolder.value();
}
private static class ValueHolder<K, V> {
private final Object lock = new Object();
private final K key;
private final ValueFactory<K,V> valueFactory;
private V value;
private ValueHolder(final K key, final ValueFactory<K, V> valueFactory) {
this.key = key;
this.valueFactory = valueFactory;
}
private V value() {
synchronized (this.lock) {
if (this.value == null) {
this.value = this.valueFactory.create(this.key);
}
return this.value;
}
}
}
One of the best programmers at work left this comment. Thanks, you know who you are!
Post a Comment