设计模式—单例模式分析

来源:互联网 发布:在线报名系统 php 编辑:程序博客网 时间:2024/05/21 12:42


      单例模式:一个类只能有一个实例


      首先,一个类要想只有一个实例,构造函数必须是私有的(如果是共有的,那就谁都可以实例化了)。其次因为构造函数是私有的,如果想外部调用这个类的话,必须要存在一个公有的静态方法。还有为了保证公有的方法返回实例的过程中实例的唯一性,这个实例应该是静态的。


      总结一下就是,单例模式有以下三个要素:

  • 私有的构造方法
  • 指向自己实例的私有静态引用
  • 以自己实例为返回值的静态的公有的方法


      单例模式根据实例化对象时机的不同分为两种:一种是饿汉式单例,一种是懒汉式单例。饿汉式单例在单例类被加载时候,就实例化一个对象交给自己的引用;而懒汉式在调用取得实例方法的时候才会实例化对象。代码如下:


      接下来来看几个网上的小例子


饿汉模式

饿汉模式—例子一:

public class Singleton {private static Singleton singleton = new Singleton();private Singleton(){}public static Singleton getInstance(){return singleton;}}

懒汉模式

懒汉模式—例子一:

public class LazyUnsafeSingleton {   private volatile static LazyUnsafeSingleton instance;   private LazyUnsafeSingleton() {   }   public static LazyUnsafeSingleton getInstance() {      if (null == instance) {         instance = new LazyUnsafeSingleton();      }      return instance;   }}

      例子一很显然在多线程下操作时不行的。当多个线程同时进入静态方法时就可能会出现多个实例。针对此修改得到例子二


懒汉模式—例子二:

public class LazyMethodSynSingleton {    private static LazyMethodSynSingleton instance;    private LazyMethodSynSingleton() {        Logger.getGlobal().info("LazyMethodSynSingleton.LazyMethodSynSingleton()");    }    public static synchronized LazyMethodSynSingleton getInstance() {        if (null == instance) {            instance = new LazyMethodSynSingleton();        }        return instance;    }}
      例子二采用方法同步,当执行静态方法的时候把这个操作定义为原子操作,来防止多线程调用,来实现一个实例。

懒汉模式—例子三:

      采用方法同步一个不好的地方就是阻塞的时间太多了,为此将同步操作定义在方法里面,进行双重校验,只有当实例为空的时候执行同步,并且为了为了防止在外层校验的时候其他现成的干扰,内层同步部分又进行一次校验。

public class LazyDoubleCheckSingleton {   private volatile static LazyDoubleCheckSingleton instance;   private LazyDoubleCheckSingleton() {      Logger.getGlobal().info("LazyDoubleCheckSingleton.LazyDoubleCheckSingleton()");   }   public static LazyDoubleCheckSingleton getInstance() {      if (null == instance) {         synchronized (LazyDoubleCheckSingleton.class) {            if (null == instance) {               instance = new LazyDoubleCheckSingleton();            }         }      }      return instance;   }}


懒汉模式—例子四:

例子三可以达到想要的效果,但是有点繁琐,利用JVM类加载机制,可以对例子三进行优化,得到例子四。

public class LazyHolderSingleton {   private static class InstanceHolder {      private static final LazyHolderSingleton INSTANCE = new LazyHolderSingleton();   }   private LazyHolderSingleton() {      Logger.getGlobal().info("LazyHolderSingleton.LazyHOlderSingleton()");   }   public static LazyHolderSingleton getInstance() {      return InstanceHolder.INSTANCE;   }}


0 0
原创粉丝点击