Java 单件工厂法

Java 单件工厂法,java,Java,工厂方法中是否可能有一个单例?我有许多使用工厂方法的域。我该如何处理这个问题。请帮我举个例子。“…为创建Singleton类实例的对象创建一个接口。这本质上是GoF书中抽象工厂、工厂方法和函子模式的组合。” 您应该从工厂方法调用getInstance()方法。getInstance()逻辑应该处理返回单例的一个实例的详细信息。单例可以实现如下功能: public class Singleton { private static Singleton mInstance; private Sin

工厂方法中是否可能有一个单例?我有许多使用工厂方法的域。我该如何处理这个问题。请帮我举个例子。

“…为创建Singleton类实例的对象创建一个接口。这本质上是GoF书中抽象工厂、工厂方法和函子模式的组合。”


您应该从工厂方法调用
getInstance()
方法。
getInstance()
逻辑应该处理返回单例的一个实例的详细信息。

单例可以实现如下功能:

public class Singleton {

private static Singleton mInstance;

private Singleton(){}

public static Singleton getInstance()
{
   if(mInstance==null){
      mInstance=new Singleton();
   }
return mInstance;
}

}

这个类可以在您想要的每个工厂方法中返回,就像前面描述的mepcotterrel一样。

在这个示例中,我相信您希望同步getInstance()方法,以确保两个线程不会同时进入它。否则,两个线程可能会在实例化单例的块内结束,这是非常有问题的。此解决方案的唯一问题是,每次调用getInstance()时,都要为方法的同步支付额外费用。 例如:

或者,您也可以切换到使用单例实例的即时初始化,而不是延迟初始化,前提是初始化成本很低,这可以保证并发性,并且不会因为调用getInstance()方法而付出同步代价。 例如:

最优化的方法是使用双重检查锁定,这需要Java 1.5或更高版本才能可靠地使用,因为在1.4或更老的JVM中volatile关键字的实现不同(请参阅O'Reilly Media,Inc.出版的第5页第182章“头先设计模式”——这是我第一次读到这篇文章的地方) 例如:


这个例子不是一个正式的工厂模式(GoF),但如果您像一个应用程序一样使用它,它仍然很有用


这并不十分清楚。你能给我们举个例子说明你在做什么吗?@Bill我想他仍在试图解决他问的问题。我想澄清一下“拥有一个单例”和“多个域”的含义会有所帮助。不:双重锁定习惯用法不好,即使它可以在1.5中实现(在此之前,它无法实现)。原因是,与更简单的同步示例相比,这样做不会带来任何好处。使用volatile并不便宜/更快,代码更冗长。所以前2个更好。@StaxMan只有在资源不处于争用状态时才正确,否则DCL示例的速度要快得多。所以我认为应该是“第一个是最好的,第二个是可以的,如果你不期望竞争”。虽然我同意DCL是不好的,但是如果您需要lazy init,那么lazy initialization holder方法是最好的。
public class Singleton {

private static Singleton mInstance;

private Singleton(){}

public static Singleton getInstance()
{
   if(mInstance==null){
      mInstance=new Singleton();
   }
return mInstance;
}

}
public static synchronized Singleton getInstance()
{
   // since whole method is synchronized only 1 thread can 
   // enter the following block ensuring only one instance 
   // is ever created. however we pay a synchronization
   // penalty every time this method is called.
   if(mInstance==null) { 
      mInstance=new Singleton();
   }
   return mInstance;
}
// no synchronization penalty, but penalty for eager init
private static Singleton mInstance = new Singleton();                          

public static Singleton getInstance()
{
    return mInstance;
}
private volatile static Singleton mInstance;

private Singleton(){}

public static Singleton getInstance()
{
   if(mInstance==null) {
      synchronized (Singleton.class) { 
          // only pay synchronization penalty once
          if(mInstance==null){
              mInstance=new Singleton();
          }
      }
   }
   return mInstance;
}
abstract class Product {}

class ConcreteProduct extends Product{}

class ProductSupportFactory {
    private static ProductSupportFactory instance = null;
    private ConcreteProduct product = null;

    static {
        instance = new ProductSupportFactory();
    }
    private ProductSupportFactory() {
        product = new ConcreteProduct(); //object initialization
    }
    public static ProductSupportFactory getInstance(){
        return instance;
    }
    public ConcreteProduct getProduct() {
        return product;
    }
    public void setProduct(ConcreteProduct product) {
        this.product = product;
    }
}

public class ProductConsumer {  
    public static void main(String args[]){ //client
        ConcreteProduct uniqueInstance = ProductSupportFactory.getInstance().getProduct();
        ConcreteProduct sharedInstance = ProductSupportFactory.getInstance().getProduct(); //same object hash
    }
}