设计模式之Singleton(单态/单态)

来源:互联网 发布:淘宝订单接口 编辑:程序博客网 时间:2024/06/17 11:25

今天学习到设计模型,发现软件设计通过单例模式可以保证系统中一个类只有一个实例而且该实例易于外界访问,从而方便对实例个数的控制并节约系统资源。如果希望在系统中某个类的对象只能存在一个,单例模式是最好的解决方案。
Singleton模式主要作用是保证在Java应用程序中,一个类Class只有一个实例存在。
在很多操作中,比如建立目录 数据库连接都需要这样的单线程操作。
还有, singleton能够被状态化; 这样,多个单态类在一起就可以作为一个状态仓库一样向外提供服务,比如,你要论坛中的帖子计数器,每次浏览一次需要计数,单态类能否保持住这个计数,并且能synchronize的安全自动加1,如果你要把这个数字永久保存到数据库,你可以在不修改单态接口的情况下方便的做到。
另外方面,Singleton也能够被无状态化。提供工具性质的功能,

Singleton模式就为我们提供了这样实现的可能。使用Singleton的好处还在于可以节省内存,因为它限制了实例的个数,有利于Java垃圾回收(garbage collection)。

我们常常看到工厂模式中类装入器(class loader)中也用Singleton模式实现的,因为被装入的类实际也属于资源。

  1. 饿汉式
public class Singleton {    private Singleton(){//私有的构造方法  防止多个实例        //do nothing;    }    private static Singleton instance = new Singleton();//静态的实例变量  static 唯一性    public static Singleton getSingleton(){//静态的获取方法  静态变量只能由静态方法获取        return instance;    }}

在这个例子里,我们可以看到单例设计模式的三要素:
1.私有的构造方法 防止多个实例

private SingleTon() {}

2.静态的实例变量 static唯一性

private static Singleton instance = new Singleton();

3.静态的获取方法 静态变量只能由静态方法获取

public static Singleton getInstance() {     return singleton;}
  1. 懒汉式
public class Singleton {    private Singleton(){}    private static Singleton instance = null;    public static Singleton getSingleton(){        if (instance==null) {            instance = new Singleton();        }        return instance;    }}

饿汉式与懒汉式的区别就在于:什么时候创建实例
饿汉式:被classload载入的时候立即就创建实例
懒汉式:用到的时候才被创建实例
可以很明显的看出当数量级上去后,懒汉式相对于饿汉式节省了不少的内存空间和创建花费的时间。
3. 线程安全
如果有两个线程要同时创建Singleton实例,当A线程cpu执行完语句if (instance==null),立即切换到B线程,同时也执行到if (instance==null)后创建了Singleton对象后,切换回A线程,又创建了一个Singleton对象,导致出现了两个Singleton对象,则使用单例模式失败了。解决这个问题我们执行要加上一个锁就可以了

public class Singleton {    private Singleton(){}    private static Singleton instance = null;    public static synchronized Singleton getSingleton(){        if (instance==null) {            instance = new Singleton();        }        return instance;    }}

4.线程安全优化
带有synchronized代码块执行都比较耗时,我们不需要为整个方法加锁。代码可以修改一下

public class Singleton {    private Singleton(){}    private static Singleton instance = null;    public static Singleton getSingleton(){        if (instance==null) {            synchronized (Singleton.class) {                instance = new Singleton();            }        }        return instance;    }}

5.Android源码中的实例:TelephonyManager

/** @hide */    private TelephonyManager() {    }    private static TelephonyManager sInstance = new TelephonyManager();    /** @hide    /* @deprecated - use getSystemService as described above */    public static TelephonyManager getDefault() {        return sInstance;    }
0 0