当前位置: 首页 > 知识库问答 >
问题:

使用工厂构建单例对象

廖令
2023-03-14

我试图用工厂创建一些单例对象:

public class MyObjectFactory {
    private MyObject myObject;

    public MyObject getInstance(boolean newInstance) {
        if (newInstance) {
            // return new object
        } else {
            // return the old object
        }
    }
}

我想使用 getInstance(布尔新实例)方法来生成一个新对象或重用现有的单例对象。

如果newInstance为true:我将生成一个新的单例对象

如果newInstance为false:如果myObject为null,则生成一个新的并返回,或者如果myObjects不为null则返回它。

而且这个getInstance(boolean newInstance)必须是线程安全的。知道怎么做吗?

共有2个答案

贺懿轩
2023-03-14

单身人士不是这样的。Singleton的全部意义在于在某个类的程序中有一个单独的实例。将你的工厂方法参数化以获得一个新的实例或者一个先前的实例不属于单例的定义。

此外,最好的辛格尔顿实现被称为比尔·皮尤·辛格尔顿

public class BillPughSingleton {

    private BillPughSingleton() {}

    public static BillPughSingleton getInstance() {
        return SingletonHelper.INSTANCE;
    }

    private static class SingletonHelper {
        private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }
}

William Pugh实现确保了多线程的安全性和最佳性能,因为只有当调用方法getInstance()时,类加载器才会加载嵌套的静态类。事实上,静态嵌套类只是外部类的静态成员(就创建时间而言,与静态字段或静态方法没有区别)。静态成员仅在使用类时创建,因此由于不能使用构造函数创建BillPughSingleton的实例,因此只有当通过getInstance()方法使用外部类时,才会生成单个线程安全实例。

如果您所要求的是创建一个新实例(如果该实例为空)或返回/覆盖现有实例。然后,您需要的不是单例,而是检索器类。此外,在设计时还应该考虑这个检索器类是否将用于多线程场景。下面是一个基本实现:

class MyRetriever {
    private static MyClass instance;

    //Private constructor to force the factory method invocation
    private MyRetriever() {}

    //Synchronizing the method in order to avoid race condition and establish a happens-before relationship between threads
    public synchronized static MyClass getInstance(boolean flagOverride) {
        if (flagOverride || instance == null){
            instance = new MyClass();
        }
        return instance;
    }
}
谷梁襦宗
2023-03-14

根据您的评论,这是实现您想要的内容的一种方法:

public class MyObjectFactory {
   private volatile MyObject inst;
   public synchronized MyObject getInstance(boolean newInstance) {
     if(newInstance) {
       inst = new MyObject(...);
     }
     return inst;
   }
}

使字段易失性意味着该值不会缓存在 CPU 中,因此更改对所有线程都是立即可见的。使方法同步可确保只有一个线程可以同时输入该方法。

 类似资料:
  • 10.2.1 结构体工厂 Go 语言不支持面向对象编程语言中那样的构造子方法,但是可以很容易的在 Go 中实现 “构造子工厂”方法。为了方便通常会为类型定义一个工厂,按惯例,工厂的名字以 new 或 New 开头。假设定义了如下的 File 结构体类型: type File struct { fd int // 文件描述符 name string // 文

  • 我正在尝试理解HK2工厂在泽西应用程序中的实现。 null 每个请求都会创建MyFactory的两个对象 单例工厂,我的理解是,工厂(MyFactory)的一个单一对象,它在注入时提供某种对象。 所以(1)应该工作还是我遗漏了什么? 当位置在下方时,位置在上方的NPE 在以下位置时,在上面位置无NPE

  • 我试图在数据库助手类中实现单例模式,但是,我似乎无法理解工厂构造函数的目的,以及是否有使用它的替代方法。

  • 我有一个代表常规路径的类路径,可以用它做一些神奇的事情。每当我想在我的应用程序中处理路径时,我都想快速实例化一个路径对象并继续使用它。Path类有一些依赖项,我想使用自动关联/依赖项注入。 我所尝试的: 我将该类作为一个服务,并创建了一个工厂方法,类似于这里所描述的:https://symfony.com/doc/current/service_container/factories.html.

  • 我正在使用google cloud build来构建我的maven项目,并使用JFrog antifactory registry来存储maven工件。云中构建需要这些工件。我尝试了几部纪录片[1],[2]。但有时会出现很多错误。我可以带上最新的指南来集成云构建和JFrog antifactory吗。正确的身份验证方法需要使用用户名密码以外的其他方法。可以使用API密钥方法。 [1].https:

  • 本文向大家介绍js简单工厂模式用法实例,包括了js简单工厂模式用法实例的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了js简单工厂模式用法。分享给大家供大家参考。具体实现方法如下: 希望本文所述对大家的javascript程序设计有所帮助。