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

一、单例模式概述

1、基本介绍

  • 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。在整个程序的运行过程中,所有该类的引用都指向同一个实例。

  • 特点:

    1. 整个程序运行过程中只有一个实例。

    2. 类必须在内部创建自己的实例。

    3. 该类必须提供一个公共方法供其它类获取这个实例。

  • 好处:

    1. 防止一个类被频繁的创建和销毁,降低了系统的资源消耗,因为只有一个实例。

    2. 避免对资源的多重占用。

2、应用场景

  • 要求生产唯一序列号。

  • WEB 中的计数器,不用每次刷新都在数据库里加一次,用单例先缓存起来。

  • 创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。

二 、单例模式的七种实现

1、饿汉式-静态常量

class Singleton{
   //1.构造器私有化
   private Singleton(){
  }

   //2.本类内部声明对象并初始化
   private final static Singleton instance = new Singleton();

   //3.对外提供一个公有的静态方法,返回实例对象
   public static Singleton getInstance(){
       return instance;
  }
}
  • 饿汉式-静态常量

    1. 构造器私有;

    2. 内部声明静态常量并初始化;

    3. 提供public方法获取实例。

  • 优点:

    1. 写法简单;

    2. 类加载时完成实例化,线程安全。

  • 缺点:

    1. 没有实现懒加载,如果没有用到该类,则会造成资源浪费。

2、饿汉式-静态代码块

class Singleton{
   //1.构造器私有化
   private Singleton(){
  }

   //2.本类内部声明对象
   private static Singleton instance;

   static {
       //静态代码块中对象实例化
       instance = new Singleton();
  }

   //3.对外提供一个公有的静态方法,返回实例对象
   public static Singleton getInstance(){
       return instance;
  }
}
  • 饿汉式-静态代码块

    1. 构造器私有;

    2. 内部声明静态常量;

    3. 通过静态代码块初始化

    4. 提供public方法获取实例。

  • 优点:

    1. 写法简单;

    2. 类加载时完成实例化,线程安全。

  • 缺点:

    1. 没有实现懒加载,如果没有用到该类,则会造成资源浪费。

3、懒汉式-线程不安全

class Singleton{

   //1.构造器私有化
   private Singleton(){
  }

   //2.本类内部声明对象
   private static Singleton instance;

   //3.对外提供一个公有的静态方法,第一次使用时实例化对象
    public static Singleton getInstance(){
       if(instance == null){
           instance = new Singleton();
      }
       return instance;
  }
}
  • 懒汉式-线程不安全

    1. 构造器私有;

    2. 内部创建静态常量;

    3. 第一次使用时实例化对象。

  • 优点:

    1. 使用时加载,避免资源浪费,只能在单线程使用。

  • 缺点:

    1. 如果多个线程同时进入if判空,则有可能创建多个实例,线程不安全。

4、懒汉式-同步关键字(线程安全)

class Singleton{

   //1.构造器私有化
   private Singleton(){
  }

   //2.本类内部声明对象
   private static Singleton instance;

   //3.对外提供一个公有的静态方法,第一次使用时实例化对象,并加入同步关键字
   synchronized public static  Singleton getInstance(){
       if(instance == null){
           instance = new Singleton();
      }
       return instance;
  }
}
  • 懒汉式-同步关键字(线程安全)

    1. 构造器私有;

    2. 内部声明静态常量;

    3. 第一次访问实例化对象;

    4. 加入synchronized同步关键字,每次只有一个线程能进入该方法。

  • 优点:

    1. 线程安全;

    2. 懒加载。

  • 缺点:

    1. 效率太低,每次调用getInstance要进行同步,不推荐使用。

5、懒汉式-双重检查(线程安全)

class Singleton{

   //1.构造器私有化
   private Singleton(){
  }

   //2.本类内部声明对象,使用volatile修改其他线程可立即感知并且防止代码重排序
   private static volatile Singleton instance;

   //3.对外提供一个公有的静态方法,第一次使用时实例化对象,并加入同步代码块双重检查
    public static  Singleton getInstance(){
       if(instance == null){
          {
               synchronized (Singleton.class){
                   if(instance == null){
                       instance = new Singleton();
                  }
              }
          }
      }
       return instance;
  }
}
  • 懒汉式-双重检查

    1. 构造器私有;

    2. 内部声明静态常量并标识volatile关键字;

    3. 第一次访问进行对象实例化,并使用双重检查机制。

  • 优点:

    1. 懒加载;

    2. 线程安全,除了刚开始多个线程可能需要进行同步,后面都不需要进入同步代码块,效率高,推荐使用。

  • 缺点:

    1. 无。

6、静态内部类

class Singleton{

   //1.构造器私有化
   private Singleton(){
  }

   //2静态内部类
   private static class SingletonInstance{
       private static final Singleton INSTANCE = new Singleton();
  }

   //3.公共方法获取实例
   public static Singleton getInstance(){
       return SingletonInstance.INSTANCE;
  }

}
  • 静态内部类

    1. 构造器私有;

    2. 提供静态类;

    3. 提供公共静态方法返回对象实例。

  • 优点:

    1. JVM在加载外部类时并不会加载内部类,只有显示调用getInstance才会对内部类进行加载,所以提供了懒加载的效果。

    2. 线程安全,JVM加载类时是单线程的。

  • 缺点:

    1. 无。

7、枚举

enum Singleton{
   //属性
   INSTANCE;
}
//获取对象
//Singleton instance = Singleton.INSTANCE;
  • 枚举

    1. 创建枚举类;

    2. 提供属性。

  • 优点:

    1. 实现简单;

    2. 多线程安全;

    3. 防止反序列化重新创建对象;

    4. 这种方式是 Effective Java 作者 Josh Bloch 提倡的方式。

  • 缺点:

    1. 无。

三、JDK实现单例模式

  • java.lang包下Runtime类

 

  • 使用了第一种饿汉式

 

posted @ 2021-10-19 18:14  冷奴  阅读(35)  评论(0)    收藏  举报