1 单例类只有一个实例对象
2 该单例类必须有单了类自行创建
3 单例类对外提供一个访问该单例的全局访问点
1 饿汉式 hungry loading
类加载到内存后就实例化一个单例,JVM保证线程安全;唯一缺点是不管是否用到类转载时就完成实例化。
public class T01_Hungry {private static final T01_Hungry INSTANCE = new T01_Hungry();private T01_Hungry() {}public static T01_Hungry getInstance() {return INSTANCE;}}
2 懒汉式 lazy loading
使用时才初始化,但存在线程不安全问题。
/*** 单例模式——懒汉式** 问题:线程不安全*/public class T02_Lazy {private static T02_Lazy instance;private T02_Lazy() {}public static T02_Lazy getInstance() {if (instance == null) {instance = new T02_Lazy();}return instance;}}
3 懒汉式改进1:getInstance方法加synchronize进行同步
通过synchronized关键字来解决线程不安全问题,但是效率会降低。
/*** 懒汉式改-进加: getInstance方法加synchronize进行同步** 问题:整个方法加锁,锁太粗,效率偏低*/public class T03_LazyWithSynchronize {private static T03_LazyWithSynchronize instance;private T03_LazyWithSynchronize() {}public static synchronized T03_LazyWithSynchronize getInstance() {if (instance == null) {instance = new T03_LazyWithSynchronize();}return instance;}}
4 懒汉式改进2:双重检查 DCL
/*** 懒汉式改 - 双重检查*/public class T04_LazyWithdoubleCheck {// volatile 语义:保证指令不乱序执行,高并发下避免获取到半加载的实例private static volatile T04_LazyWithdoubleCheck instance;private T04_LazyWithdoubleCheck() {}public static T04_LazyWithdoubleCheck getInstance() {if (instance == null) {synchronized (T04_LazyWithdoubleCheck.class) {if (instance == null) {instance = new T04_LazyWithdoubleCheck();}}}return instance;}}
5 静态内部类方式
JVM保证单例,加载外部类是不会加载内部类,可以实现懒加载
/*** 单例模式-静态内部类*/public class T05_StaticInnerClass {private T05_StaticInnerClass() {}private static class Inner {private static final T05_StaticInnerClass INSTANCE = new T05_StaticInnerClass();}public static T05_StaticInnerClass getInstance() {return Inner.INSTANCE;}}
6 枚举单例
不仅可以解决线程同步问题,还可以防止反序列化。
/*** 单例模式 - 枚举实现**/public enum T06_Enum {/*** 单例*/INSTANCE;}

