Reputation: 7775
I need a structure allowing to set a value at most once concurrently.
Something that has methods similar to putIfAbsent
and computeIfAbsent
of ConcurrentHashMap
.
interface MyContainer<T>{
void putIfAbsent(T value);
void computeIfAbsent(Supplier<T> supp);
Optional<T> maybeValue();
}
// this implementation just shows intention
class DumbContainerImpl<T> implements MyContainer<T>{
String key = "ONLYONE";
ConcurrentHashMap map = new ConcurrentHashMap<String, T>(1);
void putIfAbsent(T value){
map.putIfAbsent(key, value);
}
void computeIfAbsent(Supplier<T> supp){
map.computeIfAbsent(key, k -> supp.get());
}
Optional<T> maybeValue(){
return Optional.ofNullable(map.get(key))
}
}
Is there something similar in a standard Java library? (any JDK version)
Upvotes: 0
Views: 253
Reputation: 159086
An AtomicReference
can be used, with its compareAndSet()
method.
class AtomicContainer<T> implements MyContainer<T> {
private final AtomicReference<T> ref = new AtomicReference<>();
@Override
public boolean putIfAbsent(T value) {
if (value == null)
throw new NullPointerException();
return this.ref.compareAndSet(null, value);
}
@Override
public boolean computeIfAbsent(Supplier<T> supp) {
if (this.ref.get() == null)
return putIfAbsent(supp.get());
return false;
}
@Override
public Optional<T> maybeValue() {
return Optional.ofNullable(this.ref.get());
}
}
interface MyContainer<T> {
/**
* @return true if the given value was assigned, false if a value was already assigned
*/
boolean putIfAbsent(T value);
/**
* @return true if a value from the given supplier was assigned, false if a value was already assigned
*/
boolean computeIfAbsent(Supplier<T> supp);
Optional<T> maybeValue();
}
Upvotes: 2