java 设计模式-单例
一、单例模式定义:
单例模式确保某个了某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在实际应用中,如打印机,线程池,日志等
二、单例模式特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式保证了全局对象的唯一性
单例模式分两种:
1 类加载时候就new好了这个对象,称为 "饿汉式"
2 在需要的时候,才调用公告方法创建对象,称为 "懒汉式"
实现单例模式的方法:
1 把构造函数设置为private 防止类被随意创建对象
2 提供public的方法返回单例对象
懒汉模式:
public class Singleton{ private static Singleton uniqueInstance ; //创建单例对象的静态方法,延迟创建实例了其实 public static Singleton getInstance(){ if(null == uniqueInstance ) { uniqueInstance = new Singleton(); } return uniqueInstance ; } }
多线程情况下:
1 考虑线程安全时,创建单例的静态方法加上 synchronized ,
该方式运行效率却很低下,下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。
2 考虑多线程性能时,使用“急切”创建实例(饿汉模式)
private static Singleton uniqueInstance = new Singleton(); getInstance(){return uniqueInstance }
在类被加载时候就创建好了对象,增加了类的负担,如果是程序启动时候创建,就拖慢了程序的启动速度。
3 双重检查加锁,减少在getInstance()中使用同步 性能最好,避免整个方法被锁,只对需要锁的代码部分加锁
public class Singleton4 { // 私有构造 private Singleton4() {} private static Singleton4 single = null; // 双重检查 public static Singleton4 getInstance() { if (single == null) { synchronized (Singleton4.class) { if (single == null) { single = new Singleton4(); } } } return single; } }
4 静态内部类
public class Singleton{ private static class SingletonHolder{ public static Singleton INSTANCE = new Singleton(); } private Singleton(){} public static Singleton newInstance(){ return SingletonHolder.INSTANCE; } }
外部类加载时并不需要立即加载内部类,内部类不被加载则不去初始化,这样就不会占用内存。只有当newInstance第一次被调用时,
才会初始化INSTANCE,
第一次调用会加载SingletonHolder,这样不仅是线程安全的,也能保证单例的唯一性并且延迟了单例的实例化。
5从java1.5开始,可以使用枚举来创建单例,也是最佳方式
public enum hupObjectInstanceEnum { //枚举 INSTANCE; //属性 private EnumSingleton singleton; //构造函数 private hupObjectInstanceEnum() { singleton = new EnumSingleton() } public EnumSingleton getInstance() { return singleton ; } }
原理:java枚举创建对象是线程安全的,枚举创建对象的过程本身就是单例子,所以可以hupObjectInstanceEnum.INSTANCE的方式调用。