3

Background

I have a situation in which I'm developing a program that runs like a thread. Basically, there is a "master" program that runs instances of sub-programs simultaneously.

Due to the nature of this system, the "sub-programs" all run under a single Java Virtual Machine. The most serious implication here is that they share memory spaces.

In my sub-program, I want to create a Logger class so that all the classes within my sub-program can log to a single location. Since this project can include many classes, I want to avoid Dependency Injection and use a Singleton.

But if I use a Singleton, the instance will be stored statically. So if the JVM has 2 instances of my program running, the Logger class will give them the same instance (because they share that memory).

I want each sub-program to have their own logger, without dependency injection.

There exists a unique identifier that I can call for each program to differentiate between them.


My Current Solution

Assume "uniqueID" is an API call that the Master Program receives and then returns what Sub-Program called it. Assume this call produces extremely little computational overhead.

public class Logger {
    private static HashMap<string,Logger> instances = new Hashmap<>();

    public static Logger instance() {
        if(instances.containsKey(uniqueId)) {
            return instances.get(uniqueId);
        } else {
            Logger newLogger = new Logger();
            instances.put(uniqueId, newLogger);
            return newLogger;
        }
    }

    private Logger(){}
}

This solution allows each sub-program to treat the Logger class like a Singleton, but it's not quite a Singleton. It acts as an Instance Manager, that creates and returns instances based on which sub-program is interacting with the method.


My Question(s)

This solution is not technically a Singleton, but each project using it treats it like a singleton. What design pattern is it?

Also, is this the correct approach to my problem? How can I improve it?

Ele
  • 33,468
  • 7
  • 37
  • 75
Clay07g
  • 1,105
  • 7
  • 23

1 Answers1

1

If I read correctly, you want a thread-based multiton. Java provides the ThreadLocal class to support that pattern. With a little thought, you can implement a static logMessage() method that uses the ThreadLocal under the covers to retrieve the correct logger instance.

Care should be taken in JEE application server environments to avoid memory leaks when the application context is restarted, but I don't think that applies to your situation.

Clay07g
  • 1,105
  • 7
  • 23
Steve11235
  • 2,849
  • 1
  • 17
  • 18
  • I don't want to throw around StackOverflow guidelines and standards around (beggars can't be choosers), but I would appreciate some examples or links to examples. Or links to explain what some of that stuff means. I will do my own research on what you said. Also, keep in mind the "Master program" is not under my control. It has limits on what I can and cannot use as dependencies. For example, I can't use Java 9 or Reflection. – Clay07g Dec 04 '17 at 21:31
  • 1
    Upon simple research it seems that I've just (re)invented the "Multiton" pattern by accident. And it looks to be a legitimate technique. I will continue research into the ThreadLocal class, but thank you for helping me identify the label for my solution. +1 for that. – Clay07g Dec 04 '17 at 21:34