
[历史归档]本文原发布于 cstriker1407.info 个人博客内容为历史存档仅供参考。发布时间2013-10-13 标题设计模式学习笔记单例模式分类编程 / 设计模式 / java 标签设计模式·java·单例设计模式学习笔记单例模式1. 懒汉加载推荐2. 饿汉加载3. 枚举单例4. 双重检测DCL懒汉加载5. 登记式单例注意事项多类加载器问题Serializable 序列化问题单例模式是最常用的设计模式之一以下备忘几种常用实现方式。GitHubdesign_pattern1. 懒汉加载推荐通过内部静态类Initialization-on-demand holder实现线程安全的懒加载是最优雅的懒汉实现。publicclassSingleton_lazy{privatestaticclassSingleton_lazy_Holder{static{System.out.println(Singleton_lazy_Holder loaded);}privatestaticSingleton_lazyinstancenewSingleton_lazy();}privateSingleton_lazy(){System.out.println(Singleton_lazy instance alloced);}publicstaticSingleton_lazygetInstance(){returnSingleton_lazy_Holder.instance;}publicvoidsayHello(){System.out.println(Hello);}static{System.out.println(Singleton_lazy loaded);}}2. 饿汉加载简单直接类加载时即初始化实例天然线程安全。publicclassSingleton_hungry{privateSingleton_hungry(){}privatestaticSingleton_hungryinstancenewSingleton_hungry();publicstaticSingleton_hungrygetInstance(){returninstance;}publicvoidsayHello(){System.out.println(Hello From this.getClass().getName());}}3. 枚举单例利用 Java enum 的特性实现单例可天然防止序列化攻击和反射攻击。packagedesign_patterns.singleton;publicenumSingleton_enum{INSTANCE;publicvoidsayHello(){System.out.println(hello from enum, ii);}privateinti0;}4. 双重检测DCL懒汉加载在早期 Java 版本中存在缺陷需配合volatile使用。参考IBM DeveloperWorks - Java 中的双重检查锁定publicclassSingleton_doublecheck{privatestaticvolatileSingleton_doublecheckinstancenull;privateSingleton_doublecheck(){}publicstaticSingleton_doublecheckgetInstance(){if(nullinstance){synchronized(Singleton_doublecheck.class){if(nullinstance){instancenewSingleton_doublecheck();}returninstance;}}returninstance;}publicvoidsayHello(){System.out.println(Hello from Singleton_doublecheck);}}5. 登记式单例此处不做记录暂未接触。注意事项多类加载器问题当存在多个类加载器时单例可能失效可通过以下方式指定类加载器privatestaticClassgetClass(Stringclassname)throwsClassNotFoundException{ClassLoaderclassLoaderThread.currentThread().getContextClassLoader();if(classLoadernull)classLoaderSingleton.class.getClassLoader();returnclassLoader.loadClass(classname);}Serializable 序列化问题单例类实现Serializable时反序列化会创建新实例需通过readResolve()保证唯一性publicclassSingletonimplementsjava.io.Serializable{publicstaticSingletonINSTANCEnewSingleton();protectedSingleton(){}privateObjectreadResolve(){returnINSTANCE;}}参考cantellow.iteye.com - 单例模式calmness.iteye.com