【问题标题】:Using Singleton Design with Inheritance in a multithreaded Application在多线程应用程序中使用带有继承的单例设计
【发布时间】:2014-11-16 07:32:13
【问题描述】:

我有一个应用程序,其中的代码有点像这样编写

public Interface SuperCLass{
//....to do some methods
}

public class BaseClass1 implements SuperCLass{
//....to do some methods
}

public class BaseClass2 implements SuperCLass{
//....to do some methods
}

现在在我的应用程序中,只能为 SuperClass 引用实例化一个对象,即同步单例。

现在,我可以加入

public static synchronized  SuperCLass getInstance(){
   //initialise
}

在任何基类中,但我不能在 SuperClass 接口中包含此声明,因为我无法使用超类的引用获取基类的实例。 例如 我想这样做(这是一个非常模糊的例子)

BaseClass1 bc1 = BaseClass1.getInstance();

SuperClass sc = bc1.getInstance();

现在在代码后面的某个地方

bc1=sc.getInstance();

如何做到这一点?

注意:多个线程将访问这些对象,因此必须进行同步

【问题讨论】:

  • 为什么要显式转换为SuperClassBaseClass1 继承了“接口”。
  • 您的问题不清楚,但是仅仅将synchronized 放在单例工厂方法上肯定不会使您的单例线程安全。
  • 您的说法“使用超类的引用取回基类的实例”不清楚。
  • @Smutje 是的,没错,但是在应用程序的某个地方,我不得不通过超类引用该对象,因为我们可能不知道该实例。在这种情况下我们可以使用 instanceOf 运算符,但我试图避免这种情况
  • @MarkoTopolnik 是的,我知道...这只是为了示例...实际上我将锁定对象

标签: java multithreading inheritance design-patterns singleton


【解决方案1】:

使超类方法返回子类类型的一种方法是通过泛型。

您将无法创建 static 方法,因为您无法覆盖 static 方法,因此该技术对您无济于事,但它会变成这样:

public interface SuperClass<T extends SuperClass<T>> {

    public T getInstance();
}

public class BaseClass1 implements SuperClass<BaseClass1> {

    @Override
    public BaseClass1 getInstance() {
        // Do my create.
    }
}

但是,对于需要扩展基类的线程安全单例的特定需求,您可以使用enum 作为它们的工厂,并使用Multiton 来确保它们中只有一个。

【讨论】:

    【解决方案2】:

    为什么不使用依赖注入而不是使用单例,例如:google guice。

    Guice 将为您创建超类的实例,然后您可以通过 injector.getInstance() 方法访问它。

    【讨论】:

    • 不确定谷歌果汁...但我没有非常复杂/应用程序,所以我避免使用任何外部框架...
    【解决方案3】:

    首先,您必须同步对实例的访问。有很多关于如何做到这一点的示例(例如只读或线程安全类的线程安全发布)。

    因为单例意味着静态方法。您必须决定在某处使用哪种实现。通常这是通过setInstance 方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-07
      • 1970-01-01
      • 2010-10-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多