单例模式

  • A+
所属分类:Java设计模式

本文总结下单例模式一共有5种:饿汉、懒汉、双重锁、静态内部类、枚举。
注:这里不建议使用双重锁模式。

单例模式的概念:

单例模式必须确保某个类只能存在一个实例,并且自己提供该实例给整个系统。

单例模式的特点

    • 1.单例模式只能存在一个实例。
    • 2.单例模式必须存在一个向外提供的方法提供实例。
    • 3.必须由自己创建自己的唯一实例。

一、 饿汉式(不管你是否有使用都会创建,就是在类加载的时候就会把单例完成初始化)

  1. package design.day01;
  2. /**
  3.  * Created by on 2018/1/15.
  4.  * 单例模式,饿汉
  5.  */
  6. public class Singleton01 {
  7.   private Singleton01(){}
  8.   public static Singleton01 singleton01  = new Singleton01();
  9.   public static Singleton01 getInstance(){
  10.     return singleton01;
  11.   }
  12. }

二、 懒汉(只有在调用getInstance的时候才会去完成单例的初始化)

  1. package design.day01;
  2. /**
  3.  * Created by on 2018/1/15.
  4.  * 懒汉
  5.  */
  6. public class Singleton02 {
  7.   private Singleton02(){}
  8.   private static Singleton02 singleton02 =null;
  9.   public static synchronized Singleton02 getInstance(){
  10.     if (singleton02 == null) {
  11.       singleton02 = new Singleton02();
  12.     }
  13.     return singleton02;
  14.   }
  15. }

三、 双重锁(其实双重锁需然说有2次的null检查,但是其实性能上来说是提高了的,在单例中new的情况非常少的,很多都是读取的操作,因此在加锁先加了null的判断其实是可以减少很多的加锁,所以提高了性能)

  1. package design.day01;
  2. /**
  3.  * Created by on 2018/1/15.
  4.  * 双重锁,其实就是2次检查是否为null
  5.  */
  6. public class Singleton03 {
  7.   private Singleton03(){}
  8.   private static Singleton03 singleton03 = null;
  9.   public static Singleton03 getInstance(){
  10.     if(singleton03 == null){
  11.       synchronized (Singleton03.class){
  12.         if(singleton03 == null){
  13.           singleton03 = new Singleton03();
  14.         }
  15.       }
  16.     }
  17.     return singleton03;
  18.   }
  19. }

四、 静态内部类(支持延迟加载,并且保存线程安全)

  1. package design.day01;
  2. /**
  3.  * Created by   on 2018/1/15.
  4.  * 静态内部类
  5.  */
  6. public class Singleton04 {
  7.   private Singleton04(){}
  8.   private static class Singleton04Holder{
  9.     private static final Singleton04 singleton04 = new Singleton04();
  10.   }
  11.   public static Singleton04 getInstance(){
  12.     return Singleton04Holder.singleton04;
  13.   }
  14. }

五、 枚举(枚举除了线程安全和防止反射强行调用构造器之外,还提供了自动序列化机制,防止反序列化的时候创建新的对象)

  1. package design.day01;
  2. /**
  3.  * Created by   on 2018/1/15.
  4.  * 枚举方式
  5.  */
  6. public enum  Singleton05 {
  7.     INSTANCE;
  8.     private String name;
  9.     public String getName(){
  10.       return name;
  11.     }
  12.     public void setName(String name){
  13.       this.name = name;
  14.     }
  15. }

总结

在工作中建议使用枚举和静态内部类。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: