美文网首页
设计模式(单例模式)

设计模式(单例模式)

作者: Chenyangqi | 来源:发表于2020-11-06 11:06 被阅读0次

1、饿汉式

  • 优点:类加载的时候完成实例化,避免了线程同步问题
  • 缺点:在类加载的时候就完成实例化,没有达到Lazy Loading的效果,如果该类未使用则造成了内存浪费

可以通过静态变量和静态代码块两种方式实现,效果一样

public class Singleton1 {
   //方式1:通过静态变量方式创建
   private static final Singleton1 INSTANCE = new Singleton1();

   //方式2:通过静态代码块的方式,效果和方法1一样
//    private static final Singleton1 INSTANCE;
//
//    static {
//        INSTANCE = new Singleton1();
//    }

   /**
    * 私有的构造方法,防止产生多个对象
    */
   private Singleton1() {
   }

   /**
    * 通过该方法获得实例
    *
    * @return
    */
   public static Singleton1 getInstance() {
       return INSTANCE;
   }

   public void doSomething() {

   }
}

可通过如下方式,在多个线程中创建多个单例对象,查看创建的对象hashCode是否相同判断是否为单例

Executor executor = Executors.newCachedThreadPool();
        for (int i = 0; i < 10; i++) {
            executor.execute(new Runnable() {
                @Override
                public void run() {
                    //测试饿汉式单例
                    Singleton1 singleton1 = Singleton1.getInstance();
                    Singleton1 singleton2 = Singleton1.getInstance();
                    System.out.println(singleton1.hashCode() + "\t-----\t" + singleton2.hashCode());
                }
            });
        }

打印结果如下,不同线程下的Singleton1对象都是同一个HashCode,表示是全局单例

2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061
2007961061  -----   2007961061

2、懒汉式-线程不安全

  • 优点:做到了懒加载
  • 缺点:多线程使用的时候会产生多个实例,实际开发中不要使用这种方案
public class SingLeton2 {
   private static SingLeton2 INSTANCE;

   private SingLeton2() {
   }

   public static SingLeton2 getInstance() {
       if (INSTANCE == null) {
           INSTANCE = new SingLeton2();
       }
       return INSTANCE;
   }
}

多线程创建此单例hashcode如下,存在hashCode不一致的问题,所有没有做到全局单例

1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531
1523178316  -----   1523178316
1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531
1337000531  -----   1337000531

3、懒汉式 线程安全

  • 优点:加了同步,线程安全
  • 缺点:效率太低,开发中不推荐使用这种写法
public class Singleton3 {

   private static Singleton3 INSTANCE;

   private Singleton3() {
   }

   public static synchronized Singleton3 getINSTANCE() {
       if (INSTANCE == null) {
           INSTANCE = new Singleton3();
       }
       return INSTANCE;
   }
}

下面这种方式,虽然加锁了但是还是存在线程不安全的问题,同一时刻不同的线程走到if(instance==null)这一步时,还是会创建不同的对象

//方式二 线程不安全
   static class  Singleton7{
       private static Singleton7 instance;

       private Singleton7(){}

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

4、双重检查

  • 优点:线程安全,延迟加载,效率高
  • 开发中推荐使用这种方案
public class Singleton4 {
  private static volatile Singleton4 instance;

  private Singleton4() {
  }

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

5、静态内部类

  • 优点:线程安全,也做到了懒加载,开发中推荐使用
public class Singleton5 {
   private Singleton5() {
   }

   private static class Singleton5Instance {
       private static final Singleton5 INSTANCE = new Singleton5();
   }

   public static Singleton5 getInstance() {
       return Singleton5Instance.INSTANCE;
   }
}

6、枚举方式创建单例

  • <<Effective Java>>推荐使用这种方式创建单例,项目中推荐使用
public enum Singleton6 {
   INSTANCE;

   public void doSomething() {
       System.out.println("枚举创建");
   }

   private String name;

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }
}

相关文章

  • 单例模式Java篇

    单例设计模式- 饿汉式 单例设计模式 - 懒汉式 单例设计模式 - 懒汉式 - 多线程并发 单例设计模式 - 懒汉...

  • python中OOP的单例

    目录 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 单例

    目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计模式 是 前人...

  • 设计模式 - 单例模式

    设计模式 - 单例模式 什么是单例模式 单例模式属于创建型模式,是设计模式中比较简单的模式。在单例模式中,单一的类...

  • 设计模式

    常用的设计模式有,单例设计模式、观察者设计模式、工厂设计模式、装饰设计模式、代理设计模式,模板设计模式等等。 单例...

  • 2018-04-08php实战设计模式

    一、单例模式 单例模式是最经典的设计模式之一,到底什么是单例?单例模式适用场景是什么?单例模式如何设计?php中单...

  • python 单例

    仅用学习参考 目标 单例设计模式 __new__ 方法 Python 中的单例 01. 单例设计模式 设计模式设计...

  • 基础设计模式:单例模式+工厂模式+注册树模式

    基础设计模式:单例模式+工厂模式+注册树模式 单例模式: 通过提供自身共享实例的访问,单例设计模式用于限制特定对象...

  • 单例模式

    JAVA设计模式之单例模式 十种常用的设计模式 概念: java中单例模式是一种常见的设计模式,单例模式的写法...

  • 设计模式之单例模式

    单例设计模式全解析 在学习设计模式时,单例设计模式应该是学习的第一个设计模式,单例设计模式也是“公认”最简单的设计...

网友评论

      本文标题:设计模式(单例模式)

      本文链接:https://www.haomeiwen.com/subject/ycqtbktx.html