单例模式

单例模式有饿汉式和懒汉式两种
饿汉式是当类加载时就创建类实例,不管你用不用,先创建再说,然后每次调用的时候就不需要进行判断,节省了运行时间。
/**
* 饿汉式单例实现的示例
*/  
public class Singleton {  
  /**
   * 定义一个变量来存储创建好的类实例,直接在这里创建类实例,只会创建一次
   */  
  private static Singleton uniqueInstance = new Singleton();  
  /**
   * 私有化构造方法,好在内部控制创建实例的数目
   */  
  private Singleton(){  
      //  
  }  
  /**
   * 定义一个方法来为客户端提供类实例
   * @return 一个Singleton的实例
   */  
  public static Singleton getInstance(){  
      //直接使用已经创建好的实例  
      return uniqueInstance;  
  }  

  /**
   * 示意方法,单例可以有自己的操作
   */  
  public void singletonOperation(){  
      //功能处理  
  }  
  /**
   * 示意属性,单例可以有自己的属性
   */  
  private String singletonData;  
  /**
   * 示意方法,让外部通过这些方法来访问属性的值
   * @return 属性的值
   */  
  public String getSingletonData(){  
      return singletonData;  
  }  
}

懒汉式是每次获取实例的时候进行判断,看看是否需要进行创建实例,需要判断的时间,当没人使用的时候,就不会创建实例,节省内存空间。
public class Singleton {  
  //4:定义一个变量来存储创建好的类实例  
  //5:因为这个变量要在静态方法中使用,所以需要加上static修饰  
  private static Singleton instance = null;  
  //1:私有化构造方法,好在内部控制创建实例的数目  
  private Singleton(){      
  }  
  //2:定义一个方法来为客户端提供类实例  
  //3:这个方法需要定义成类方法,也就是要加static  
  public static Singleton getInstance(){  
      //6:判断存储实例的变量是否有值  
      if(instance == null){  
          //6.1:如果没有,就创建一个类实例,并把值赋值给存储类实例的变量  
          instance = new Singleton();  
      }  
      //6.2:如果有值,那就直接使用  
      return instance;  
  }  
}


线程安全方面:
1.不加同步的懒汉式是不安全的,因为当两个线程调用 getInstance()方法时,A线程已经判断结束,但是还没有创建实例,而B线程正在进行判断,这个时候就会出错创建出两个实例出来。
2.饿汉式是安全的,因为虚拟机在装载类的时候不会出现并发的状况
3.实现懒汉式的线程安全问题,加上synchronized,但是这样一来速度更慢饿了
public static synchronized Singleton getInstance(){}
4.双重检查枷锁机制:并不是每次进入getInstance方法都要同步,而是先不同步,进入方法后,先检查实例是否存在,如果不存在才进入下面的同步快,这是一重检查。进入同步块后,再次检查实例是否存在,如果不存在,就在同步的情况下创建一个实例,这是第二重检查。
双重检查枷锁机制的实现会使用一个关键字volatile,它的意思是:被volatile修饰的变量的值不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存,从而确保多个线程能正确处理该变量。
public class Singleton {  
  /**
   * 对保存实例的变量添加volatile的修饰
   */  
  private volatile static Singleton instance = null;  
  private Singleton(){      
  }  
  public static  Singleton getInstance(){  
      //先检查实例是否存在,如果不存在才进入下面的同步块  
      if(instance == null){  
          //同步块,线程安全的创建实例  
          synchronized(Singleton.class){  
              //再次检查实例是否存在,如果不存在才真的创建实例  
              if(instance == null){  
                  instance = new Singleton();  
              }  
          }  
      }  
      return instance;  
  }  
}

提示:由于volatile关键字可能会屏蔽掉虚拟机中的一些必要的代码优化,所以运行效率并不高,因此没有必要不要使用。
类级内部类:有static修饰的成员式内部类。
类级内部类相当于其外部类的static成分,他的对象与外部类对象间不存在依赖关系,因此可直接创建。
类级内部类相当于其外部类的成员,只有在第一次被使用的时候才会被加载。
public class Singleton {  
  /**
   * 类级的内部类,也就是静态的成员式内部类,该内部类的实例与外部类的实例
   * 没有绑定关系,而且只有被调用到才会装载,从而实现了延迟加载
   */  
  private static class SingletonHolder {  
      /**
       * 静态初始化器,由JVM来保证线程安全
       */  
      private static Singleton instance = new Singleton();  
  }  
  /**
   * 私有化构造方法
   */  
  private Singleton() {  
  }  
  public static  Singleton getInstance() {  
      return SingletonHolder.instance;  
  }  
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值