单例模式-----创建型模式
单例模式是一种创建型模式,提供了一种创建对象的方式,保证只有一个类,提供唯一的访问的对象方式。特点:单例类至于一个实例,必须给其他对象提供这一实例的访问方法。
常见的单例模式
饿汉式(线程安全,效率高,不能延迟加载)
类初始化时,立即加载这个对象(没有延时加载),加载类时,天然的线程安全的
class Singleton {
// 1.私有构造方法,其他类不能访问该构造方法了
private Singleton() {
}
// 2.创建本类对象
private static Singleton s = new Singleton();
// 3.对外提供公共的访问方法
public static Singleton getInstance() { // 获取实例
return s;
}
}
懒汉式(线程安全,效率不高,可以延迟加载)
可能出现两个线程同时请求,为了保证单例,所以加synchronized关键字但是会导致调用效率不高
class Singleton
{
// 1.私有构造方法,其他类不能访问该构造方法了
private Singleton()
{}
// 2.声明一个引用
private static Singleton s;
// 3.对外提供公共的访问方法,如果为空则创建,不为空则直接返回
public static synchronized Singleton getInstance()
{
if(s == null)
{
s = new Singleton();
}
return s;
}
}
双重检测锁式(由于jvm底层内部模型原因,偶尔会出问题,不建议使用,所以没有去研究代码)
将同步模式放在if模块底下,只有在第一次初始化才会同步,其他情况直接返回
静态内部类式(线程安全,调用效率高,可以延迟加载)
public class SingletonDemo{
private static class SingletonClassInstance{
private static final SingletonDemo instance = new SingletonDemo();
}
public static SingletonDemo getInstance(){
return SingletonClassInstance. Instance;
}
private SingletonDemo(){
}
}
枚举单例(线程安全,调用效率高,不能延迟加载)
枚举本身就是单例模式,由jvm从根本保障上提供保障,避免了通过反射和反序列化的漏洞
单例模式的应用场景
Windows的回收站和任务管理器采用单例模式,因为在实际应用中不需要打开两个窗口的必要性,假设我每次打开回收站或任务管理器都需要消耗大量资源,但每个回收站或者任务管理器的资源都是共享的;再比如网上的计数器,如果存在多个计数器,每个用户上网就刷新一次计数器的值,那么是难以同步的;根据以上生活中的例子来说,单例模式应用的适用场景:需要生成唯一序列的环境;需要频繁实例化然后销毁的对象;经常用到但每次创建对象都会消耗大量资源的对象;方便资源相互通信的环境。也可以总结出单例的优点:实现了对唯一实例访问的可控;对于一些需要频繁销毁和创建的对象来说提高了系统性能;正是由于这样,所以单例模式不适合频繁变化的对象;如果实例化的对象长时间不使用就会被当作垃圾回收。