设计模式之单例模式

一. 概念:

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

二.要点:

  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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值