单例模式特征 1、私有的构造方法,不对外开放的 2、通过一个静态方法或者枚举返回单例类到对象 3、注意多线程的场景 4、注意单例类对象在反序列化时不会重新创建对象 几种不同的单例模式: 1、懒汉式单例,是线程不安全的 static class Singleton1 { // 私有的静态变量 private volatile static Singleton1 sInstance = null; // 私有的构造方法 private Singleton1() { System.out.println("懒汉式单例。。。"); } // 公有的静态方法,是线程不安全的 // public static Singleton1 getInstance() { // if (sInstance == null) { // sInstance = new Singleton1(); // } // return sInstance; // } // 修改为线程安全的,但同步锁粒度太大,很耗性能 // public static synchronized Singleton1 getInstance() { // if (sInstance == null) { // sInstance = new Singleton1(); // } // return sInstance; // } // 双重校验DCL public static synchronized Singleton1 getInstance() { if (sInstance == null) { synchronized (Singleton1.class) { if (sInstance == null) { sInstance = new Singleton1(); // 1.给sInstance实例分配对象 // 2.调用Singleton1构造方法,初始化成员字段 // 3.Singleton1对象赋值sInstance // jdk 乱序 会导致DCL失效 jdk1.5后使用volatile禁止指令重排 } } } return sInstance; } } 2、饿汉式单例,线程安全 static class Singleton2 { private static Singleton2 sInstance = new Singleton2(); private Singleton2() { } public static Singleton2 getInstance() { return sInstance; } } 3、静态内部类单例,线程安全,并且可以延迟加载 static class Singleton3 { private Singleton3() { } private static class Holder { private static final Singleton3 INSTANCE = new Singleton3(); } public static final Singleton3 getInstance() { return Holder.INSTANCE; } } 4、枚举类型单例,默认是线程安全的 static enum Singleton4 { INSTANCE; } 5、使用容器 static class SingletonManager { private static Map<String, Object> objMap = new HashMap<>(); public static void registerService(String key, Object instance) { if (!objMap.containsKey(key)) { objMap.put(key, instance); } } public static Object getService(String key) { return objMap.get(key); } }
几种单例模式
最新推荐文章于 2024-09-13 17:30:19 发布