单例模式,是一种常用的软件设计模式。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例。
具体的思路是:
(1)别人不能new实例,所以要将构造方法私有化,使其不能在类的外部通过new关键字实例化该类对象。
(2)在该类内部产生一个唯一的实例化对象,并且将其封装为private static类型。
(3)定义一个静态方法返回这个唯一对象。
一、饿汉式
立即加载就是使用类的时候已经将对象创建完毕(不管以后会不会使用到该实例化对象,先创建了再说。很着急的样子,故又被称为“饿汉模式”),常见的实现办法就是直接new实例化。
public class Singleton {
// 初始化一个
private static final Singleton INSTANCE = new Singleton();
// 让别人不能new
private Singleton() {
}
// 保证别人能获取(getInstance:获取实例)
public static Singleton getInstance() {
return INSTANCE;
}
}
public class Client {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
Singleton instance3 = Singleton.getInstance();
System.out.println(instance1 == instance2); // true
System.out.println(instance2 == instance3); // true
}
}
二、懒汉式
延迟加载就是调用get()方法时实例才被创建(先不急着实例化出对象,等要用的时候才给你创建出来。不着急,故又称为“懒汉模式”),常见的实现方法就是在get方法中进行new实例化。
public class Singleton {
// 初始化一个
private static Singleton INSTANCE;
// 让别人不能new
private Singleton() {
}
// 保证别人能获取(getInstance:获取实例)
public static Singleton getInstance() {
if (INSTANCE == null){
INSTANCE = new Singleton();
}
return INSTANCE;
}
}
public class Client {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
Singleton instance3 = Singleton.getInstance();
System.out.println(instance1 == instance2); // true
System.out.println(instance2 == instance3); // true
}
}
这种懒汉式在多线程环境中是完全错误的,根本不能保证单例的状态!!
三、内部类实现单例(懒汉式)
这种也是懒汉式的一种实现,而且使用这种懒汉式没有任何的线程问题,大家来思考,结合咱们上边的内容,只要不调用getInstance()方法,就不会使用内部类,内部类一旦被使用只会被初始化一次,以后一直用的就是静态常量 INSTANCE 了。
public class Singleton {
// 让别人不能new
private Singleton() {
}
// 获取实例
public static Singleton getInstance() {
return SingletonHolder.INSTANCE;
}
// 静态内部类会在第一次使用的时候加载一次,静态常量会在类加载后初始化,一次!
private static class SingletonHolder {
private static final Singleton INSTANCE = new Singleton();
}
}
public class Client {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
Singleton instance3 = Singleton.getInstance();
System.out.println(instance1 == instance2); // true
System.out.println(instance2 == instance3); // true
}
}