核心作用:
包装一个类只有一个实例,并且提供一个访问该实例的全局访问点。
常见应用场景:
windows的任务管理者(Task Manager)就是很典型的单例模式; 在spring中,每个Bean默认就是单例的,这样做的优点是spring容器可以管理; 在servlet编程中, 每个servlet也是单例; 项目中,读取配置文件的类,一般也只有一个对象,没有必要每次使用配置文件数据,每次new一个对象去读取。
单例模式优点:
由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其它依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式类解决。 单例模式可以在系统设置全局的访问点,优化共享资源访问,例如可以设计一个单例类,负责所有数据表的映射处理。
常见的五种单例模式实现方式:
主要: 饿汉式(线程安全,调用效率高。但是,不能延时加载) 懒汉式(线程安全,调用效率低。但是,可以延时加载) 其它: 双重检查锁(线程安全,可以延时加载。建议使用) 静态内部类(线程安全,调用效率高。并且,可以延时加载) 枚举单例(天生线程安全,调用效率高。但是,不能延时加载)
饿汉式:
/*** 饿汉式 --->线程安全,方法没有同步,效率高!但是,没有延时加载优势* 1,构造器私有化,避免外部直接创建对象* 2,声明一个私有的静态属性 并 创建该对象* 3,创建一个对外的公共的静态方法,访问该变量,* @author admin**/
public class SingLeton {/*** 2,声明一个私有的静态属性 并 创建该对象* 类初始化时,立即加载这个对象(没有延时加载优势),加载类时,天然的是线程安全的!(所有。。)*/ private static SingLeton instance =new SingLeton();/*** 1,构造器私有化,避免外部直接创建对象*/private SingLeton() {}/**3,创建一个对外的公共的静态方法,访问该变量。* 方法没有同步,效率高!* @return*/public static SingLeton getInstance(){ //return instance; }
}
懒汉式:
/*** 懒汉式--->线程安全,调用效率不高!但是,可以延时加载* 1,构造器私有化,避免外部直接创建对象* 2,声明一个私有的静态属性* 3,创建一个对外的公共的静态方法,访问该变量,如果变量没有对象,创建该对象, * @author admin*/
public class SingLeton {/*** 类初始化时,不初始化这个对象(延时加载,真正用的时候在创建)*/private static SingLeton instance;/*** 私有构造器只供自己使用*/private SingLeton() {}/*** 方法同步,效率低* @return*/public static synchronized SingLeton getInstance(){if(null==instance){instance =new SingLeton();}return instance;}
}
静态内部类:
/*** ͨ 通过静态内部类实现単例模式* 这种方法:线程安全,调用效率高,并且实现了延时加载* @author admin*/
public class SingLeton { /*** 只有调用getInstance()方法时,这个类才会被加载* @author admin*/private static class SingLetonInstance{private static final SingLeton instance=new SingLeton();} private SingLeton() {} /*** 方法没有同步,效率高!* @return*/public static SingLeton getInstance(){return SingLetonInstance.instance; }
}
枚举单例
/**
* 枚举式实现単例模式!(没有延时加载)
* 可以天然防止反射和反序列化漏洞
* @author admin
*/
public enum SingLeton{/*** 这个枚举元素,本身就是単例对象*/Instance; /*** 可以添加自己需要的操作*/public void SingLeton(){}
}
双重检查锁
/*** 通过双重检查锁实现単例模式* 线程安全,可以延时加载。建议使用* @author admin*/
public class Singleton {private static volatile Singleton instance;private Singleton() {}public Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;}
}