4.单例模式

  • 一、定义
    • 保证一个类仅有一个实例,并提供一个访问它的全局访问点
  • 二、适用场景
    • 对于频繁使用对象,可节省创建对象所花费时间,但是对象的状态频繁的变化就不适合单例模式了
    • new操作变少,因而对系统内存的使用频率降低,减轻GC压力,缩短GC停顿时间
  • 三、实例
    • 通常在单例模式在Java语言中,有两种构件方法:
    1. 饿汉方式:指全局的单例实例在类装载时构建
    2. 懒汉方式:指全局的单例实例在第一次被使用时构建
    • 饿汉方式(线程安全)
      public class Singleton1 {
          //在静态初始化器中创建单例实例,这段代码保证了线程安全
          private static Singleton1 uniqueInstance = new Singleton1();
    
          //Singleton类只有一个构造方法并且是被private修饰的,所以用户无法通过new方法创建该对象实例
          private Singleton1(){}
    
          public static Singleton1 getInstance(){
            return uniqueInstance;
          }
      }
    • 懒汉方式(非线程安全)
       public class Singleton2 {
           private static Singleton2 uniqueInstance;
    
           private Singleton2 (){
           }
    
           //没有加入synchronized关键字的版本是线程不安全的
           public static Singleton2 getInstance() {
           //判断当前单例是否已经存在,若存在则返回,不存在则再建立单例
           if (uniqueInstance == null) {
               uniqueInstance = new Singleton2();
           }
    
           return uniqueInstance;
      }
    • 懒汉式(线程安全)
       public class Singleton3 {
           private volatile static Singleton3 uniqueInstance;
    
           private Singleton3 (){
           }
    
           //没有加入synchronized关键字的版本是线程不安全的
           public static Singleton3 getInstance() {
    
               synchronized(Singleton3.class) {
                   //判断当前单例是否已经存在,若存在则返回,不存在则再建立单例
                   if (uniqueInstance == null) {
                      uniqueInstance = new Singleton3();
                   }
               }
    
               return uniqueInstance;
           }
       }     
    • 懒汉式(双重检查加锁版本)
       public class Singleton4 {
           //volatile保证,当uniqueInstance变量被初始化成Singleton实例时,多个线程可以正确处理uniqueInstance变量
           private volatile static Singleton4 uniqueInstance;
    
           private Singleton4() {
           }
    
            public static Singleton4 getInstance() {
    
               //检查实例,如果不存在,就进入同步代码块
               if (uniqueInstance == null) {
                   //只有第一次才彻底执行这里的代码
                   synchronized (Singleton4.class) {
                       //进入同步代码块后,再检查一次,如果仍是null,才创建实例
                       if (uniqueInstance == null) {
                           uniqueInstance = new Singleton4();
                       }
                   }
               }
    
               return uniqueInstance;
           }
      }
    • 懒汉式(登记式/静态内部类方式)
       public class Singleton5 {
           private static class SingletonHolder {
               private static final Singleton5 INSTANCE = new Singleton5();
           }
    
           private Singleton5 (){}
    
           public static final Singleton5 getInstance() {
               return SingletonHolder.INSTANCE;
           }
       }             
    • 饿汉方式(枚举方式)
       ////这种实现方式还没有被广泛采用,但这是实现单例模式的最佳方法。 它更简洁,自动支持序列化机制,绝对防止多次实例化 (如果单例类实现了Serializable接口,默认情况下每次反序列化总会创建一个新的实例对象)
       public enum  Singleton6 {
           //定义一个枚举的元素,它就是 Singleton 的一个实例
           INSTANCE;
    
           public void doSomeThing() {
              System.out.println("枚举方法实现单例");
           }
       }

猜你喜欢

转载自www.cnblogs.com/zhongj/p/11239349.html