您的位置:首页 > 其它

2.偏头痛杨的常见设计模式入门系列之单例模式篇

2017-10-23 14:13 309 查看
前戏
众所周知,java的类是允许实例化n个实例&对象的,但有一些场景下,
我们不允许也没必要让使用者创建那么多的实例&对象来浪费内存,造成系统性能下降,我们需要对类进行计划生育。
例如数据库连接池对象、spring容器对象、hibernate的sessionFactory对象等等,
我们只希望某个类在全局范围内只有一个实例&对象,那我们就需要使用单例模式。

什么是单例模式
单例模式确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例。
这个类就被称为单例类,这个模式就叫单例模式。

单例模式是设计模式中最最最常用以及简单的设计模式,工厂模式中的工厂也需要单例模式。
spring的所有自定义bean默认都是单例的,除非显式的设计scope="prototype"。
spring推荐将所有业务逻辑组件,DAO组件,数据源组件等配置成单例的行为方式,
因为这些组件无需保存任何用户状态,所以所有客户端都可以共享这些组件。

单例模式的优点
减少创建java实例所带来的系统开销。
便于系统跟踪单个java实例的生命周期,实例状态等。

手动实现单例模式
1.为了保证该类只能创建一个实例,程序不能允许自由创建该类的对象。
必须使用private修饰构造器,将该类的构造方法隐藏起来、私有化,保证外部无法创建该类实例。

2.提供一个public static方法作为该类的访问入口,用于创建该类的对象。
因为调用该方法时有可能还没有对象,只能是用类来调用,并且全局只有一个实例,故用static,
一般方法名为getInstantce()。

3.该类需要在内存中缓存已创建的对象(使用private static类变量保存),否则该类无法知道是否曾经创建过实例。

此外单例模式通常有两种实现形式:
懒汉式:在第一次获取实例时创建对象。需要在获取对象时加个if判断,还要加一个synchronized关键字,
防止多线程情况下,创建2次对象。

饿汉式:在类加载时创建对象,可见恶汉比较着急,因为他饿啊。
因为是在类加载时就加载对象,如果后面不使用,会造成一定的内存浪费,尤其在对象很大的情况下。

总结:其实真的不用太拘泥于懒汉还是恶汉,这样太矫情了。
使用懒汉式,如果不加synchronized,你多创建了一次对象又如何,内存浪费了多少?本身就是小概率事件,
如果要加synchronized后,会造成同步锁,大幅度降低并发性能,访问变成串行,并发情况下都在堵塞ing。
使用饿汉式,就算后面不调用,浪费的那点内存又如何?更何况怎么会不被调用呢?不被调用那你写他干什么呢?

所以不要太纠结,一个男人成熟的标志就是懂得取舍。
懒汉式单例类

public class Singleton{
  private static Singleton instance;
  private Singleton(){}
  public static

synchronized
Singleton getInstance(){
   

if(instance==null){
      //也可以在直接在代码上加锁,加锁之前需先判断if(instance==null),提升性能。
      instance = new Singleton();
    }
    return instance;
  }
}

测试代码:
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1==s2);//返回true,代表2个变量是引用的一个相同的实例&对象

饿汉式单例类

public class Singleton{
  private static Singleton instance =
new Singleton();
  private Singleton(){}
  public static Singleton getInstance(){
    return instance;
  }
}
测试代码:
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1==s2);//返回true,代表2个变量是引用的一个相同的实例&对象

总结
单例模式是所有设计模式中最简单、最常用的设计模式,没有之一,请大家务必理解并掌握。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: