Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
324 views
in Technique[技术] by (71.8m points)

concurrency - Is there a standard solution in Java for concurrent value set exactly once?

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)

question from:https://stackoverflow.com/questions/66065586/is-there-a-standard-solution-in-java-for-concurrent-value-set-exactly-once

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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();

}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...