【问题标题】:A Singleton with multiple instances?具有多个实例的单例?
【发布时间】:2017-12-04 21:18:40
【问题描述】:

背景

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

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

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

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

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

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


我目前的解决方案

假设“uniqueID”是主程序接收然后返回子程序调用它的 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,但它并不完全是 Singleton。它充当实例管理器,根据与方法交互的子程序创建和返回实例。


我的问题

这个解决方案在技术上不是一个单例,但每个使用它的项目都把它当作一个单例。 它是什么设计模式?

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

【问题讨论】:

    标签: java multithreading static singleton


    【解决方案1】:

    如果我没看错,您需要一个基于线程的multiton。 Java 提供了 ThreadLocal 类来支持该模式。稍加思考,您就可以实现一个静态 logMessage() 方法,该方法在后台使用 ThreadLocal 来检索正确的记录器实例。

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

    【讨论】:

    • 我不想到处乱扔 StackOverflow 指南和标准(乞丐不能成为选择者),但我希望能提供一些示例或示例链接。或链接来解释其中一些东西的含义。我会根据你说的做我自己的研究。另外,请记住“主程序”不在我的控制之下。它对我可以和不能用作依赖项的内容有限制。例如,我不能使用 Java 9 或 Reflection。
    • 经过简单研究,我似乎只是偶然(重新)发明了“Multiton”模式。它看起来是一种合法的技术。我将继续研究 ThreadLocal 类,但感谢您帮助我确定解决方案的标签。为此 +1。
    猜你喜欢
    • 1970-01-01
    • 2021-03-16
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多