码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之单例模式分析

时间:2015-05-22 13:37:38      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:设计模式   线程同步   java   


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


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


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

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


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


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


饿汉模式

饿汉模式—例子一:

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;
   }
}


设计模式之单例模式分析

标签:设计模式   线程同步   java   

原文地址:http://blog.csdn.net/zhangzhengyi03539/article/details/45914153

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!