学习设计模式——单例模式

来源:互联网 发布:无线信号探测软件 编辑:程序博客网 时间:2024/04/30 09:38

适用于:

  • 程序中最多只有该类的一个实例,并提供一个全局访问点
    如:缓存、线程池、偏好设置对象、打印机等设备驱动程序、日志对象等

优点:

  • 减少内存开支,尤其在创建或销毁频繁使用的对象时。
  • 避免对资源多重占用,比如写文件
  • 设置全局访问点,优化和共享资源访问

缺点:

  • 没有接口,难扩展,因为其要求“自身实例化”,所以接口或抽象类都是没有意义的。
  • 对测试也不利
  • 单例模式与单一职责原则有冲突。

单例模式入门:

1.懒汉式

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

2.饿汉式

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

懒汉式用时间换空间,没有人使用就不会创建实例。
饿汉式用空间换时间,不管用不用都创建。


单例模式进阶:

懒汉式进阶——双重检查加锁

懒汉式如果不加synchronized关键字的话是线程不安全的。
而饿汉式是线程安全。

如果在创建实例的方法上加synchronized关键字能使得线程安全,但是会影响性能,而通过双重检查加锁可以减少性能的影响。

public class Singleton {    // volatile 只适用于jkd1.5及以上,而且会屏蔽一些优化代码,所以运行效率不高,没有特别需要不要轻易使用。    private volatile static Singleton uniqueInstance = null;    private Singleton() {    }    public static Singleton getInstance() {        if (uniqueInstance == null) {            // 第一次创建时同步,以后就不需要同步了            synchronized (Singleton.class) {                if (uniqueInstance == null) {                    uniqueInstance = new Singleton();                }            }        }        return uniqueInstance;    }}

饿汉式进阶——Initialize-on-demand Holder Class idiom

public class Singleton {    //用静态的内部类,是线程安全的    private static class SingletonHolder {        // 在内部类创建实例,由于是静态实例,所以是唯一的        private static Singleton instance = new Singleton();    }    private Singleton() {    }    public static Singleton getInstance() {        return SingletonHolder.instance;    }}

单例模式最佳实现——枚举

public enum Singleton {    uniqueInstance;}

用枚举实现单例模式简洁、高效、安全


单例模式扩展:

控制实例的数量

public class Singleton {    private static int maxNum = 2;    private static int index = 0;    private static Vector<Singleton> vector = new Vector<Singleton>();    static {        for (int i = 0; i < maxNum; i++) {            vector.add(new Singleton());        }    }    private Singleton(){    }    public static Singleton getInstance(){        Random random = new Random();        index = random.nextInt(maxNum);        return vector.get(index);    }}
0 0
原创粉丝点击