Have static method return the same instance for the same string argument

user842225 :

I have a TrafficMonitor class, inside the class, I have a factory static method to return an instance of this class:

public class TrafficMonitor {
   private String busNumber;
   //private constructor
   private TrafficMonitor(String busNumber) {
       this.busNumber = busNumber;
   }

   // static factory method to return a instance of this class
   public static TrafficMonitor forBus(String busNumber) {
       // how to make sure one instance per busNumber???
       return new TrafficMonitor(busNumber);
   }

}

I don't want the TrafficMonitor to be a singleton overall. But inside the static factory method forBus(String busNumber), I would like to make sure the same instance of TrafficMonitor is return for the same busNumber. That's "singleton" per busNumber. How to achieve it?

For example following code should use the same instance of TrafficMonitor:

// monitor1 and monitor2 are referring to the same instance
TrafficMonitor monitor1 = TrafficMonitor.forBus("123");
TrafficMonitor monitor2 = TrafficMonitor.forBus("123");

Following code should use different instances of TrafficMonitor:

// monitor1 and monitor2 are two different instances
TrafficMonitor monitor1 = TrafficMonitor.forBus("123");
TrafficMonitor monitor2 = TrafficMonitor.forBus("456");

And I want to have the static factory method be thread safe as well. That's if two threads call it for the same bus number, two threads should use the same instance as well.

John Kugelman :

Add instances to a static map. Use computeIfAbsent to return the existing instance if the key already exists or create a new one if it doesn't.

A ConcurrentMap ensures thread safety.

private static ConcurrentMap<String, TrafficMonitor> instances = new ConcurrentHashMap<>();

public static TrafficMonitor forBus(String busNumber) {
    return instances.computeIfAbsent(busNumber, TrafficMonitor::new);
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=323145&siteId=1