单例模式的定义
单例模式是指确保一个类在任何情况下都只有一个实例,并且提供一个访问该单例的全局访问点。
如何创建一个单例模式
构造函数需要是 private 访问权限的,这样才能避免外部通过 new 创建实例;
考虑对象创建时的线程安全问题;
考虑是否支持延迟加载;
考虑 getInstance() 的性能(是否加锁)
单例模式适用的场景
J2EE 标准中的 ServletContext 和 ServletContextConfig;
Spring 框架应用中的 ApplicationContext、数据库中的连接池等也都是单例模式。
饿汉式(饥渴型)单例模式
在类加载的时候就创建对象,不会出现线程安全问题(因为还没有开始加载的时候就创建好了对象,线程都没有机会去争夺)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package SingletonFactoryModel;
public class SingletonHungry { static SingletonHungry s = new SingletonHungry(); private SingletonHungry(){} private static SingletonHungry getInstance(){ return s; }
public static void main(String[] args) { SingletonHungry instance = SingletonHungry.getInstance(); SingletonHungry instance1 = SingletonHungry.getInstance(); System.out.println(instance1 == instance);
} }
|
懒汉式(懒狗)单例模式
懒汉式:在需要的时候才创建,类加载时不创建对象, 直接创建对象可能会有线程安全问题,导致重复创建不同对象,通过施加 双重校验锁来实现对同一对象的获取
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package SingletonFactoryModel;
public class SingletonLazy {
private volatile static SingletonLazy singletonLazy;
private SingletonLazy(){}
public static SingletonLazy getInstance() { if (singletonLazy == null) { synchronized (SingletonLazy.class){ if(singletonLazy == null){ singletonLazy = new SingletonLazy(); } } } return singletonLazy; }
public static void main(String[] args) { SingletonLazy instance = SingletonLazy.getInstance(); SingletonLazy instance1 = SingletonLazy.getInstance(); System.out.println(instance == instance1); } }
|