有多个实例的Singleton?

时间:2017-12-04 21:18:40

标签: java multithreading static singleton

背景

我有一种情况,我正在开发一个像线程一样运行的程序。基本上,有一个"主人"同时运行子程序实例的程序。

由于该系统的性质,"子程序"所有都在一个Java Virtual Machine下运行。这里最严重的含义是它们共享内存空间。

在我的子程序中,我想创建一个Logger类,以便我的子程序中的所有类都可以记录到一个位置。由于这个项目可以包含很多类,我想避免依赖注入并使用单例。

但是如果我使用Singleton,实例将被静态存储。因此,如果JVM有2个程序运行实例,Logger类将为它们提供相同的实例(因为它们共享该内存)。

我希望每个子程序都有自己的记录器,没有依赖注入。

我可以为每个程序调用唯一标识符来区分它们。


我当前的解决方案

假设" uniqueID"是主程序接收的API调用,然后返回子程序所称的API调用。假设此调用产生极少的计算开销。

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(){}
}

这个解决方案允许每个子程序像单例一样处理Logger类,但它不是一个单例。它充当实例管理器,根据子程序与方法交互来创建和返回实例。


我的问题

此解决方案在技术上不是Singleton,但使用它的每个项目都将其视为单例。 它的设计模式是什么?

另外,这是解决我问题的正确方法吗?我该如何改进?

1 个答案:

答案 0 :(得分:1)

如果我读得正确,你想要一个基于线程的multiton。 Java提供了ThreadLocal类来支持该模式。稍加思考,您可以实现一个静态logMessage()方法,该方法使用封面下的ThreadLocal来检索正确的记录器实例。

在重新启动应用程序上下文时,应注意JEE应用程序服务器环境以避免内存泄漏,但我认为这不适用于您的情况。