Java 设计模式-单例
2016-07-19 10:25
267 查看
单例设计要点
保证该类只有一个实例。将该类的构造方法定义为私有方法,这样其他的代码就无法通过调用该类的构造方法来实例化该类的对象。提供一个该实例的访问点。一般由该类自己负责创建实例,并提供一个静态方法作为该实例的访问点。
饿汉式和懒汉式的区别
饿汉式:声明实例,引用时即实例化。懒汉式:静态方法第一次被调用前不实例化,即懒加载。对于创建实例代价大,且不定会使用时,使用懒加载模式可以减小开销。
实现单例模式的九种方法
1. 线程不安全的懒汉式 - 多线程不可用public class Singleton{ private static Singleton Instance; private Singleton(){}; public static Singleton getInstance{ if(Instance == null){ Instance = new Singleton(); } return Instance; } }
优点:达到懒加载效果。
缺点:只有在单线程下能保证只有一个实例,多线程下创建多个实例有风险。
2. 同步方法下的懒汉式 - 可用,不推荐
public class Singleton{ private static Singleton Instance; private Singleton(){}; public static Synchronized Singleton getInstance{ if(Instance == null){ Instance = new Singleton(); } return Instance; } }
优点:线程安全,可以保证正常使用下(不考虑使用反射调用私有构造方法)只有一个实例。
缺点:每次获取实例都要申请锁,开销大,效率低。
3. 同步代码块下的懒汉式 - 不可用
public class Singleton{ private static Singleton Instance; private Singleton(){}; public static Singleton getInstance{ if(Instance == null){ synchronized(Singleton.class){ Instance = new Singleton(); } } return Instance; } }
优点:不需要在每次调用时加锁,效率比同步方法下的懒汉式要高。
缺点:虽然使用了synchronize同步,但本质上是线程不安全的。
4. 不正确双重检查下的懒汉式 - 不推荐
public class Singleton{ private static Singleton Instance; private Singleton(){}; public static Singleton getInstance{ if(Instance == null){ synchronized(Singleton.class){ if(Instance == null){ Instance = new Singleton(); } } } return Instance; } }
优点:使用了双重检查,很大程度上避免了线程不安全,同时避免了不必要的锁开销。
缺点:依然存在创建多个实例的可能,因为每个线程都有自己的一份拷贝,并不能保证实例化后将Instance的引用拷回主内存,不能保证对其他线程立即可见,所以仍然可能造成多个实例被创建。
5. 正确双重检查下的懒汉式 - 推荐
public class Singleton{ private static volatile Singleton Instance; private Singleton(){}; public static Singleton getInstance{ if(Instance == null){ synchronized(Singleton.class){ if(Instance == null){ Instance = new Singleton(); } } } return Instance; } }
优点:使用双重检查,同时使用volatile修饰Instance,避免由于多线程同步与可见性问题造成的多个实例。
缺点:NA
6. 静态常量 饿汉式 - 推荐
public class Singleton{ private static final Singleton Instance = new Singleton(); private Singleton(){}; public static Singleton getInstance{ return Instance; } }
优点:实现简单,无线程同步问题。
缺点:在类加载时完成实例化。若该类实例一直未被使用,则会造成资源浪费。
7. 静态代码块 饿汉式 - 可用
public class Singleton{ private static Singleton Instance; static{ Instance = new Singleton(); } private Singleton(){}; public static Singleton getInstance{ return Instance; } }
优点:无线程同步问题。
缺点:类装载时创建实例,无懒汉加载。实例一直未被使用时会浪费资源。
8. 静态内部类 推荐
public class Singleton{ private Singleton(){}; public static Singleton getInstance{ return InnerClass.Instance; } private static class InnerClass{ private static final Singleton Instance = new Singleton(); } }
优点:无线程同步问题,实现了懒加载,因为只有调用getInstance时才会装载内部类,才会创建实例。
缺点:NA
8 . 枚举 - 不推荐
public enum Singleton{ Instance; public void whatSoEverMethod() }
优点:无线程同步问题,且能防止通过反射创建新对象。
缺点:使用的枚举,而非类。同时单一实例的访问点也不是一般单例模式的静态方法。
相关文章推荐
- 部门树状图用JAXB解决
- springmvc拦截器处理
- struts2工作原理
- Java--泛型的原理以及使用场景
- Spring+SpringMVC+Mybatis 多数据源整合
- spring mvc 创建 rest api
- Java并发编程 - 逐级深入 看线程的中断
- SpringMVC的Handler处理及url映射
- Thinking in Java之类内部变量定义先后顺序
- Java内部类的小结
- struts漏洞
- SpringMVC
- java内部类、数据类型转换
- Java的图片处理工具类ImageUtils
- spring mvc的基本使用和struts2的区别
- java根据字符串获取类名
- Java 中的高阶函数
- 帆软报表嵌入eclipse网页工程中
- ajax get提交后台乱码问题
- Spring事务Transaction配置的五种注入方式详解