Java设计模式之单例模式(Singleton Pattern)

来源:互联网 发布:淘宝跟天猫的区别 编辑:程序博客网 时间:2024/06/05 19:05

Singleton Pattern

单例模式:确保一个类只有一个实例,而且自行实例化并向整个系统提供这个实例,这个类为单例类,它提供全局访问的方法.单例类是一种对象创建型模式.

这是官方的说法,但看着还是不知道怎么用怎么办呢?我们可以想象这种设计模式的应用场景,比如一个国家只能有一个最高领导人,这时候我们是不是该使用单例模式了呢?

目的

  • 保证一个类仅有一个实例,并提供一个访问它的全局访问点.

主要解决

  • 一个全局使用的类频繁地创建与销毁.

何时使用

  • 当想控制实例数目,节省系统资源的时候.

怎么解决

  • 判断系统是否已经有这个单例,如果有则返回,如果没有则创建.

步骤

如果我想写一个下载的管理类,而且在整个系统中只能实例化一次,来节省资源.那么请看…

  • (1)让单例类的构造函数为private,确保单例类的唯一性,这样就不会被实例化.
private DownloadManager(){}
  • (2)在单例类中声明一个静态的私有成员变量,确保单例类唯一的同时让外部可以访问这个唯一实例.
private static DownloadManager dm=null;
  • (3)增加一个公有的静态方法,使其外部可以访问该类的成员变量并实例化.
public static DownloadManager getInstance(){   if(dm==null){       dm=new DownloadManager();     }   return dm;}

这么一来简洁明了,这样就完了?这确实只new了一个实例啊…..,可是如果是多线程的话是不是就又会创建多个实例了.那就不是单例模式了.为什么呢? 因为我们还没有加锁 synchronized,当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。哪接下来我们就用双检锁/双重校验锁,使用synchronized进行加同步锁.还有一点必须记住,使用双检锁/双重校验锁需要在私有静态变量dm之前加上volatile修饰符.被volatile修饰的成员变量可以确保多个线程都能够正确处理.

class DownloadManager{    //创建一个静态的对象   private volatile static DownloadManager dm=null;    //让构造方法为private   private DownloadManager(){}   public static DownloadManager getInstance(){        if(dm==null){            synchronized(DownloadManager.class){                if(dm==null){                    //实例化唯一对象                dm=new DownloadManager();                  }            }        }   return dm;   }}

总结

  • 优点:在内存中只有一个实例,减少内存的开销,避免对资源的多重利用.
  • 缺点:一个类应该只关心内部的逻辑,而不在意外部怎么实例化的.
  • 注:1.单例类只有一个实例.2.单例类必须自己创建自己的唯一实例.3.单例类必须给所有的其他对象提供这一实例.

最后

我的Github地址,欢迎STAR

1 0
原创粉丝点击