1、简介
单例较简单,分为饿汉式(加载类时创建)、懒汉式(使用时创建)、双检索(为线程安全)
2、场景
例如:
- 工厂(SqlSessionFactoryBean、)
- 上下文(ApplicationContext、ServletContext、SecurityContext、...)
- 系统环境信息(ProcessEnvironment)
- 连接池()
等、、、
3、举例
1.1 饿汉式
饿汉式主要是在初始化类时创建不可变静态对象,这样在程序启动后,无论多少次通过getInstance获取【构造器私有,不能通过new创建】Person类,都只能拿到同一个对象。
创建Person类
public class Person {
private String name;
private String age;
//初始化时创建对象
private static final Person instance = new Person();
/**
* 私有构造器
*/
private Person(){}
/**
* 获取单例对象
* @return
*/
public static Person getInstance(){
return instance;
}
}
测试
public class MainTest {
public static void main(String[] args) {
Person instance1 = Person.getInstance();
Person instance2 = Person.getInstance();
System.out.println(instance1 == instance2);
}
}
1.2 懒汉式
懒汉式主要在通过getInstance方法获取对象时做判断。如果没有,创建对象,赋值属性,返回属性。如果对象不为空,返回已存在的对象。
创建Anima类
public class Animal {
private String name;
private String age;
private static Animal instance;
private Animal(){}
public static Animal getInstance(){
//为空时创建对象,放在属性上
if(instance == null){
instance = new Animal();
}
return instance;
}
}
测试
public class MainTest {
public static void main(String[] args) {
Animal instance3 = Animal.getInstance();
Animal instance4 = Animal.getInstance();
System.out.println(instance3 == instance4);
}
}
1.3 双检索+内存可见性
-- 双检索单例主要是为了保证线程安全的同时,使锁住的代码块足够小,以增加效率。
-- 因为创建对象过程中线程不安全,需要对instance属性加volatile使instance属性内存可见
创建Clothes类
public class Clothes {
private String color;
private String type;
private volatile static Clothes instance;
private Clothes(){};
public static Clothes getInstance(){
if(instance == null){
synchronized (Clothes.class){
if(instance == null){
instance = new Clothes();
}
}
}
return instance;
}
}
测试
public class MainTest {
public static void main(String[] args) {
Clothes clothes1 = Clothes.getInstance();
Clothes clothes2 = Clothes.getInstance();
System.out.println(clothes1 == clothes2);
}
}
end...