设计模式--单例模式

单例设计模式

设计模式 :不是技术,是开发人员,为了解决某些问题实现的写代码的经验.

所有的设计模式核心的技术,就是面向对象.一共有 23种设计模式,会在今后逐个分享

1. 单例模式

保证一个类的对象在内存中的唯一性

实现步骤

  • 私有修饰构造方法

  • 创建本类的成员变量, 不new对象

  • 方法get,返回本类对象

//饿汉式
public class Single {
   private Single(){}
   
   // 自己创建自己的对象, 不允许其他地方 调用这个类的构造方法
   private static Single s = new Single();
   
   public static Single getInstance(){
       return s;
  }
}

//懒汉,对象的延迟加载,用到的时候才去加载
public class Single {
   private Single(){}

   private static Single s = null;

   public static Single getInstance(){
       if (s == null) {
           s = new Single();
      }
       return s;
  }
}
 public static void main(String[] args) {
       //静态方法,获取Single类的对象
       Single instance = Single.getInstance();
}

 

2. 懒汉式的安全问题

一个线程判断完变量 s=null,还没有执行new对象,被另一个线程抢到CPU资源,同时有2个线程都进行判断变量,对象就可能创建多次

    public static Single getInstance(){
       synchronized (Single.class) {
           //判断变量s,是null就创建
           if (s == null) {
               s = new Single();
          }
      }
       return s;
  }

性能问题 : 第一个线程获取锁,创建对象,返回对象. 第二个线程调用方法的时候,变量s已经有对象了,根本就不需要在进同步,不要在判断空,直接return才是最高效的.双重的if判断,提高效率 Double Check Lock

private static volatile Single s = null; 
public static Single getInstance(){
       //再次判断变量,提高效率
       if(s == null) {
           synchronized (Single.class) {
               //判断变量s,是null就创建
               if (s == null) {
                   s = new Single();
              }
          }
      }
       return s;
  }

3. 关键字volatile

上述的双重检查锁定机制,DCL机制理论上是完美的,但不幸的是,现实完全不同,双重检查锁定的问题是:并不能保证它会顺利执行

主要原因是java 平台的内存模型允许无序写入,并会对一些指令进行重排序,重排序之后多个线程执行这个单例模式时,各个线程之间可能会信息同步不及时,错位,导致实例化多次对象

解决方法是 使用 volatile 修饰某个字段,java 线程内存模型就会确保所有线程看到这个变量的值是一致的,同时还会禁止指令重排序,

成员变量修饰符,不能修饰其它内容

  • 关键字作用 :

    • 保证被修饰的变量,在线程中的可见性

    • 防止指令重排序

public class Single {

   private static volatile Single  s ;
   
   private Single(){}

   public static  Single getInstance(){
       if(s == null ){
           synchronized (Single.class){
               if(s==null){
                   s = new Single();
              }
          }
      }
       return s;
  }
}
public class Demo01 {
   public static void main(String[] args) {

       Single single1 = Single.getInstance();
       Single single2 = Single.getInstance();
       Single single3 = Single.getInstance();
       Single single4 = Single.getInstance();

       System.out.println(single1);
       System.out.println(single2);
       System.out.println(single3);
       System.out.println(single4);
  }
}
// 打印执行结果:多次调用方法 ,得到的都是同一个对象
com.single.Single@61bbe9ba
com.single.Single@61bbe9ba
com.single.Single@61bbe9ba
com.single.Single@61bbe9ba
 

 

posted @ 2022-05-08 23:04  ziperson  阅读(20)  评论(0)    收藏  举报
//雪花飘落效果