单例模式
单例模式,顾名思义就是只有一个实例,并且自己负责创建自己的对象,这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
1、懒汉式:
简介:实例在用到的时候才去创建,判断是否有实例,没有则创建;
缺点:线程不安全,当有多个线程并行调用 getInstance() 的时候,就会创建多个实例。也就是说在多线程下不能正常工作;
解决方法:可以加上synchronized,让其编程线程安全的;
//懒汉式:
public class LazySingle {
private static LazySingle instance; //首先不创建对象
private LazySingle() {} //不能通过实例化创建对象
public static LazySingle getinstance(){ //可以加上`synchronized`,使其线程安全
if (instance == null){
instance = new LazySingle(); //判断完之后再创建对象
}
return instance;
}
}
2、饿汉式:
简介:实例在初始化的时候就已经建好了,无论你是否都实例,都一样会创建的;线程安全的;
缺点:占用内存空间高,浪费空间;
//饿汉式:
public class HungrySingle {
private static final HungrySingle instance = new HungrySingle();
private HungrySingle() { }
public static HungrySingle getInstance(){
return instance;
}
}
3、双检锁模式:
简介:其用了两层判断,既是线程安全的,又不会浪费空间;
问题:在 JVM 的即时编译器中存在指令重排序的优化。即双检锁的运行步骤具有不确定性,结果也无法预测;
解决:在声明变量时加上volatile;
//双重锁检验模式:
public class LockSingle {
private volatile static LockSingle instance; //加上,避免指令重排而导致的多线问题
private LockSingle(){ };
public static LockSingle getInstance(){
if (instance == null){ //第一次检验是否实例化对象
synchronized (LockSingle.class){ //第二次同步锁检验
if (instance == null){
instance = new LockSingle();
}
}
}
return instance;
}
}
4、静态内部类模式:
简介:其线程安全,且除了调用该方法之外,没有其他方式可以调用它,读取实例时不会进行同步,没有性能内存的问题;
//静态内部类模式:
public class InnerSingle {
private static class SingleHolder{
private static final InnerSingle instance = new InnerSingle();
}
private InnerSingle(){};
public static final InnerSingle getInstance(){
return SingleHolder.instance;
}
}
5、枚举模式:
简介:枚举默认就是线程安全的,而且还能防止反序列化导致重新创建新的对象。总之,其他模式所带有的问题,他都可以解决;
//枚举模式:
public enum EnumSingle {
INSTANCE;
public EnumSingle getInstance(){
return INSTANCE;
}
}

浙公网安备 33010602011771号