1)单例模式使用场景:需要频繁的进行创建和销毁的对象,或者创建对象耗费资源过多,但又经常用到的对象,如工具类对象,数据源对象,session工厂等。
2)懒汉式和饿汉式优缺点
饿汉式
优点:写法简单,类加载时完成实例化对象, 避免了线程同步问题,线程安全。
缺点:类加载时完成实例化,没有达到lazy loading的效果,如果用不到这个实例,会造成内存的浪费。
/** * 饿汉式 */ public class Single1 { private Single1(){} private final static Single1 single1 = new Single1(); public static Single1 getSingle1() { return single1; } }
懒汉式
优点:起到了lazy loading的效果
缺点:仅单线程可用,多线程不安全
/** * 懒汉式 */ public class Single2 { private Single2(){} private static Single2 single2; public static Single2 getSingle2() { if (single2 == null){ single2 = new Single2(); } return single2; } }
懒汉式改进(同步方法)
优点:解决了线程安全问题。
缺点:每次获得实例都要进行同步,效率太低。
/** * 懒汉式改进:同步方法 */ public class Single3 { private Single3(){} private static Single3 single3; public static synchronized Single3 getInstance() { if (single3 == null) { single3 = new Single3(); } return single3; } }
双重检查(同步代码块的字节码文件,并进行双重检查)
优点:双重检查是多线程开发常用的,保证了线程安全,仅创建实例时同步一次,又是lazy loading,推荐开发时使用
/** * 懒汉式改进:同步代码块,双重检查 */ public class Single4 { private Single4(){} private static Single4 single4; public static Single4 getInstance() { if (single4 == null) { synchronized (Single4.class){ if (single4 == null) { single4 = new Single4(); } } } return single4; } }
静态内部类
调用getInstance方法才会装在内部类,从而完成实例化 ,类的静态属性只会在第一次加载类的时候初始化,JVM帮助我们保证了线程的安全性,在类初始化时,别的线程无法进入。
优点:保证线程安全,利用静态内部类特点实现延迟加载,效率高,推荐使用
/** * 静态内部类实现单例 */ public class Single5 { private Single5(){} public static Single5 getInstance() { return Single5Inner.single5; } static class Single5Inner{ private static final Single5 single5 = new Single5(); } }
使用枚举
借助JDK1.5中添加的枚举来实现单例,不仅避免多线程同步问题,还能防止反序列化重新创建新的对象。
推荐使用
/** * 枚举实现单例 */ public enum Single { SINGLE; }
原文:https://www.cnblogs.com/tongge521/p/13207632.html