单例设计模式

设计模式的总原则是开闭原则:对扩展开放,对修改封闭。在程序需要进行拓展的时候,不能去修改原有的代码,而是要扩展原有代码。

1.  单列设计模式

某个类只有一个实例,而且自行实例化,并且向整个系统提供这个实例。总之,选择单列设计模式就是为了防止不一致的状态。打印机就被设计成单例,每台计算机都可以有若干台打印机,但只能有一个打印机后台处理程序,以免两个打印作业同时输出到打印机。单例设计模式主要分为2种:饿汉式和懒汉式。

饿汉式

单例设计模式

在类初始化的时候已经自行实例化了一个静态对象,供系统使用,以后不再改变,所以天生是线程安全的。

懒汉式:

单例设计模式

把构造函数的访问修饰符设置为private,防止类在外部被实例化。在同一个虚拟机范围内,Singleton2的唯一实例只能通过getInstance()方法访问。在多线程的情况下,不是线程安全的。可能会出现多个Singleton2的实例。有4种线程安全的方式:同步锁、双重检查锁定、静态内部类、枚举法。

同步锁:

单例设计模式

该方法虽然线程安全了,但是每次调用getInstance()来访问实例时,都要加锁,加锁是一个特别耗性能的操作,效率低下。

双重检查锁定:

单例设计模式

比上一种方法好一点,只有改单例对象还没有创建的时候才需要加锁,线程安全。但是2次if操作,代码实现起来比较复杂。

静态内部类:

单例设计模式

利用了类加载器的性能保证初始化single时只有一个线程,所以也是线程安全的,也没有性能损耗。

枚举:

单例设计模式

自由序列化,只有一个实例,线程安全。

饿汉式和懒汉式的区别:

1)  饿汉式是线程安全,懒汉式本身不是线程安全的。可用以上4种方法可以实现线程安全。

2)  资源加载和性能:饿汉式在类初始化的时候就创建了一个静态对象,不管之后用不用这个单例,他都会占据一定的内存。但是相应的,第一次调用时速度会很快,因为其资源已经加载出来。而懒汉式会延迟加载,在第一次使用该单例的时候才会实例化对象,第一次调用时要做初始化,需要资源加载,所以性能上面会有延迟。之后就和饿汉式就一样了。