单例模式
一、饿汉式
1、构造器私有化
2、类的内部创建静态对象
3、向外暴漏一个静态的公共方法
public class Singleton {
private Singleton() {
}
private final static Singleton singleton = new Singleton();
public static Singleton getInstance(){
return singleton;
}
}
测试
public class client {
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance1==instance2);
System.out.println("instance1:"+instance1.hashCode());
System.out.println("instance2:"+instance1.hashCode());
/**
* 问题 在类装载的时候就完成实例化,如果没有用过这个实例,就会造成内存浪费
*/
}
}
结果:
true
instance1:460141958
instance2:460141958
还有一种饿汉式采用的是静态代码块初始化类的实例
static{
instance = new instance();
}
二、懒汉式
1、在类的内部声明一个类的实例。
2、在类中搞个私有的无参构造器
3、提供一个静态的公有方法,创建这个实例
public class Singleton02 {
private static Singleton02 singleton02;
private Singleton02() {
}
public static Singleton02 getSingleton02(){
if(singleton02 == null){
singleton02 = new Singleton02();
}
return singleton02;
}
}
测试
public class client02 {
public static void main(String[] args) {
Singleton02 instance01 = Singleton02.getSingleton02();
Singleton02 instance02 = Singleton02.getSingleton02();
System.out.println(instance01==instance02);
System.out.println("instance01="+instance01.hashCode());
System.out.println("instance02="+instance02.hashCode());
/**
* 问题 ,采用反射的爆破处理,使得单例模式中的懒汉式不安全
*/
Constructor<Singleton02> declaredConstructor = Singleton02.class.getDeclaredConstructor(null);
declaredConstructor.setAccessible(true);
Singleton02 instance3 = declaredConstructor.newInstance();
Singleton02 instance4 = declaredConstructor.newInstance();
System.out.println(instance3==instance4);
System.out.println("instance3:="+instance3);
System.out.println("instance4:="+instance4);
}
}
结果:
true
instance01=460141958
instance02=460141958
三、采用枚举解决单例模式安全性问题
1、枚举类
2、返回枚举
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance() {
return INSTANCE;
}
}
测试:
public class Test {
public static void main(String[] args) {
EnumSingle instance1 = EnumSingle.INSTANCE;
EnumSingle instance2 = EnumSingle.INSTANCE;
System.out.println(instance1==instance2);
System.out.println("instance1:="+instance1.hashCode());
System.out.println("instance2:="+instance2.hashCode());
}
}
结果:
true
instance1:=460141958
instance2:=460141958