Java单例模式


  • 背景知识:Static关键字
  • 在对于定义类的变量,分为两种,是否具有static修饰的变量;
  • 没有static修饰的变量,通过类的实例化(对象)引用,改变量称为实例变量
  • 使用static修饰的变量称之为类变量(也称之静态变量),类变量不通过类的实例化来引用,可类名直接引用;
  • 二者区别:
  • 实例变量: JVM为每个新创建的对象分配独立的内存空间;
  • 类变量: 是所有对象共有的;
  • 引用方式:
  • 实例变量: 对象名.变量名
  • 类变量: 类名.变量名
  • 使用类变量的优点:减少开辟新的内存空间,直接引用固有变量。
  • 本概念也可以引入至实例方法和类方法;

  • 定义:该类只有一个实例,并且自行实例化向整个系统提供该实例;(由如一个国家只有一个皇帝,并只能指定某个人为皇帝);
  • 单例模式是应用最广泛的模式之一:
  • 作用:单例模式可以避免系统创建过多对象,从而减少过多资源消耗;
  • 适用场景
  1. 该系统资源只具有该类一个实例化对象:例如改家公司只具有一个打印机;
  2. 创建一个对象,需消耗的资源过多的情况下,可以使用单例模式。(例:访问IO和数据库连接池建立);
  • 注意点:
  • 构造方法不对外开放,一般为Private;
  • 单例模式的构造函数私有化,使得客户端代码无法以New 的方式实例化该类对象,只会暴露一个公有化静态方法;
例:
Person person = new Person();
Connection connection = DruidUtils.getConnection();

懒汉模式

  • 特点:当使用时才进行实例化,采用以时间换空间的方式;
  • 优点:一定程度上节约资源;
  • 缺点:第一次加载时才进行实例化,反应慢;

饿汉模式

  • 特点:调用时,即进行类的实例化,采用以空间换时间的方式;

代码参考:将单例模式与计算正方形面积结合在一起;

  • AreaHunger:

package singleinstance;



public class AreaHunger {



       // Create an instance directly.

       private static AreaHunger instance = new AreaHunger();

       

       // Private constructor. Can't visit it from outside's class.

       private AreaHunger() {

              

       }

       

       // Return an instance directly.

       public static AreaHunger getInstance() {

              return instance;

       }

       

       // Caculate the square area.

       public static UserTest getHunger(int x) {

              System.out.println("The square area are  " + (x*x));

              return null;

       }

       

}
  • AreaLazy

package singleinstance;



public class AreaLazy {



       // In inner to create an instance.

       private static AreaLazy instance = null;

       

       // Private constructor. Can't visit it from outside's class.

       private AreaLazy() {

              

       }

       

       // Provide a public static method to visit from outside.

       public static AreaLazy getInstance() {

              if(instance == null) {

                     return new AreaLazy();

              }

              return new AreaLazy();

       }

       

       

       // Caculate the square's area.

       public static UserTest getSquareArea(int x) {

              System.out.println("The square are are " + (x*x));

              return null;

       }

}
  • UserTest(用于测试)

public class UserTest {



       public static void main(String[] args) {

              // TODO Auto-generated method stub

              

              UserTest manOne = AreaLazy.getSquareArea(4);

              UserTest manTwo = AreaHunger.getHunger(8);

       }



}
  • Console:(控制台运行结果)
The square are are 16

The square area are  64