设计模式之单例模式

来源:互联网 发布:2016淘宝小号购买平台 编辑:程序博客网 时间:2024/06/05 20:25

一. 概念:

保证一个类仅有一个实例,并提供一个访问它的全局访问点,这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象

二.要点:

  1. 某个类只能有一个实例
  2. 它必须自行创建这个实例
  3. 它必须自行向整个系统提供这个实例

三.优点:

  1. 在内存里只有一个实例,减少了内存的开销,避免频繁的创建和销毁实例
  2. 避免对资源的多重占用(比如写文件操作)。

四.缺点:

  1. 当一个单例的对象长久不用时,不会被jvm的垃圾收集机制回收
  2. 不能继承

五.常见使用场景

  1. 要求生产唯一序列号。
  2. WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。
  3. 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

六. 三种比较好的实现单例模式的写法:

1. 枚举 Enum (Java单例模式最佳实现方式)

public enum Singleton {      INSTANCE;      public void whateverMethod() {       System.out.println("Hello World!");     }  }  

引用:

public class SingletonPatternDemo {   public static void main(String[] args) {     Singleton.INSTANCE.whateverMethod();   }}

结果就输出Hello World!

用enum实现的好处:
1. 利用的枚举的特性实现单例
2. 由JVM保证线程安全
3. 序列化和反射攻击已经被枚举解决
调用方式为Singleton.INSTANCE, 出自《Effective Java》第二版第三条: 用私有构造器或枚举类型强化Singleton属性。(enum 在JDK1.5中加入)

2. 饿汉式

public class Singleton{    //类加载时就初始化    private static final Singleton instance = new Singleton();    private Singleton(){}    public static Singleton getInstance(){        return instance;    }//可以根据需求特定函数  public void whateverMethod() {       System.out.println("Hello World!");     }  }

引用:

public class SingletonPatternDemo {   public static void main(String[] args) {    Singleton.getInstance().whateverMethod();   }}

优点:线程安全,没有加锁,执行效率会提高。
缺点:它不是一种懒加载模式(lazy initialization) instance 在类装载时就被实例化,即使客户端没有调用 getInstance()方法,从而可能浪费了内存。饿汉式的创建方式在一些场景中将无法使用:譬如 Singleton 实例的创建是依赖参数或者配置文件的,在 getInstance() 之前必须调用某个方法设置参数给它,那样这种单例写法就无法使用了。

3. 内部静态类

public class Singleton {      private static class SingletonHolder {      private static final Singleton INSTANCE = new Singleton();      }      private Singleton (){}      public static final Singleton getInstance() {      return SingletonHolder.INSTANCE;      }   //可以根据需求特定函数  public void whateverMethod() {       System.out.println("Hello World!");     }  }   

引用:

public class SingletonPatternDemo {   public static void main(String[] args) {    Singleton.getInstance().whateverMethod();   }}

优点:是一种懒加载模式(lazy initialization),避免了饿汉式instance 在类装载时就被实例化的问题 。因为 SingletonHolder 是私有的,除了 getInstance() 之外没有办法访问它,只有显示通过调用 getInstance 方法时,才会显示装载 SingletonHolder 类,这时而 instance才会被实例化。

七.总结什么情况下该用什么写法:

一般情况下直接使用饿汉式就好了,当明确要求要懒加载(lazy initialization)时则使用静态内部类,当涉及到反序列化创建对象时则使用枚举的方式来实现单例。

更多单例模式的写法推荐阅读:
http://www.runoob.com/design-pattern/singleton-pattern.html

转载请注明出处:
http://blog.csdn.net/fzw_faith/article/details/52887799

1 0