单例模式(singleton):
核心作用:保证一个类只有一个实例,并且提供一个访问该实例的全局访问点.
常见应用场景:
win的task manager(任务管理器)
win的recycle bin(回收站)
项目中,读取配置文件的类一般只有一个对象
网站的计数器
应用程序的日志应用
数据库连接池的设计
操作系统的文件系统
application
spring中,每个bean默认为单例
servlet编程中,每个servlet也是单例
springmvc/strust1框架中,控制器对象也是单例
优点:
减少系统性能开销
可以在系统设置全局的访问点,优化共享资源访问
常见五中单例模式实现方式:
主要:
饿汉式(线程安全,调用效率高.不能延时加载)
懒汉式(线程安全,调用效率不高.但能延时加载)
其他:
双重检测锁式
静态内部类式(线程安全,调用效率高.可以延时加载)
枚举单例(线程安全,调用效率高,不能延时加载)
饿汉式:(单例对象立即加载)
public class SingletonDemo02{
private static /*final*/ SingletonDemo02 s = new SingletonDemo02();
private SingletonDemo02(){}// 私有化构造器
public static /*synchronized*/ SingletonDemo02 getInstance(){ return s; }
}
懒汉式:(单例对象延时加载)
public class SingletonDemo01(){
private static SingletonDemo01 s;
private SingletonDemo01(){}
public static synchronized SingletonDemo01 getInstance(){
if(s == null){
s = new SingletonDemo01();
}
return s;
}
}
实现延迟加载
问题:资源利用率高,但是每次getInstance方法都要同步,并发效率低
静态内部类:懒加载
public class SingletonDemo04{
private static class SingletonClassinstance{
private static final SingletonDemo04 instance = new SingletonDemo04();
}
public static SingletonDemo04 getInstance(){
return SingletonClassinstance.instance;
}
private SingletonDemo04(){}
}
要点:
外部类没有static属性,不会立即加载
只有真正调用getInstance(),才会加载静态内部类.加载时是线程安全的.
兼顾并发高效和延迟加载
枚举:
public enum SingletonDemo05{ /** *定义一个枚举的元素,它就代表了singleton的一个实例 */
INSTANCE; /** *单例可以有自己的操作 */
public void singletonOperation(){
//功能处理
}
}
优点:
实现简单
枚举本身就是单例模式.由JVM从根本上提供保障,避免通过反射和反序列化的漏洞
缺点:
无延迟加载
如何选用:
单例对象 占用 资源少, 不需要 延时加载
枚举 好于 饿汉式
单例对象 占用 资源大,需要 延时加载
静态内部类 好于 懒汉式