设计模式------单例模式(一)

  单例模式在现实开发中几乎无所不在,数据库建立连接,iOC创建对象,winfrom创建窗口,读取配置文件等等。

  单例模式应用的场景一般发现在以下条件下:

  (1)资源共享的情况下,避免由于资源操作时导致的性能或损耗等。如上述中的日志文件,配置。

  (2)控制资源的情况下,方便资源之间的互相通信。如线程池等。


       实现单利模式的原则和过程:
  1.单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例
  2.单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式调用取得实例的方法如getInstance时才会实例化对象)
  3.单例模式要素:
    a.私有构造方法
    b.私有静态引用指向自己实例
    c.以自己实例为返回值的公有静态方法

  1.饿汉式:单例实例在类装载时就构建,急切初始化。(预先加载法)

/**
* 饿汉式
*
*/
public class Test {
private Test() {
}
public static Test instance = new Test();
public Test getInstance() {
return instance;
}
}

  优点
  1.1.线程安全
  1.2.在类加载的同时已经创建好一个静态对象,调用时反应速度快
  缺点
  资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化

  2.懒汉式:单例实例在第一次被使用时构建,延迟初始化。 

class Test {
        private Test() {
        }
        public static Test instance = null;
        public static Test getInstance() {
                if (instance == null) {
              //多个线程判断instance都为null时,在执行new操作时多线程会出现重复情况
                        instance = new Singleton2();
                }
                return instance;
        }
}


  优点: 
    避免了饿汉式的那种在没有用到的情况下创建事例,资源利用率高,不执行getInstance()就不会被实例,可以执行该类的其他静态方法。 
  缺点: 
    懒汉式在单个线程中没有问题,但多个线程同事访问的时候就可能同事创建多个实例,而且这多个实例不是同一个对象,虽然后面创建的实例会覆盖先创建的实例,但是还是会存在拿到不同对象的情况。解决这个问题的办法就是加锁synchonized,第一次加载时不够快,多线程使用不必要的同步开销大。 

  3.双重检测 其实就是懒汉模式的升级版

class Test {
        private Test() {
        }
        public static Test instance = null;

        public static Test getInstance() {
                if (instance == null) {
                        synchronized (Test.class) {
                                if (instance == null) {
                                        instance = new Test();
                                }
                        }
                }
                return instance;
        }
}


  优点 
      资源利用率高,不执行getInstance()就不被实例,可以执行该类其他静态方法 ,弥补了懒汉模式下的多线程下的安全。
  缺点 
      第一次加载时反应不快,多次判断效率低一点

  4.静态初始化  由于是在自己被加载时就已经实例化,所以 这种也是属于饿汉式

public sealed class Test {
        private Test() {
        }

       public    static readonly Test instance = new Test();

        public static Test GetInstance() {
                return instance;
        }
}

优点 
     
线程安全,写法简单。
  缺点 
      
资源效率不高,可能getInstance()永远不会执行到,但执行该类的其他静态方法或者加载了该类(class.forName),那么这个实例仍然初始化

人生匆匆几十年,BeYourself...
原文地址:https://www.cnblogs.com/huagege/p/7526893.html