版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tangyaliang11/article/details/79833310
单例模式保证一个类只有一个对象,并且提供一个访问该实例的全局访问点。
1.单例模式实例一(饿汉式)
public class Singleton {
private static Singleton sin = new Singleton(); /// 直接初始化一个实例对象
private Singleton() { /// private类型的构造函数,保证其他类对象不能直接new一该对象的实例
}
public static Singleton getSin() { /// 该类唯一的一个public方法
return sin;
}
}
上述代码中的一个缺点是该类加载的时候就会直接new 一个静态对象出来,当系统中这样的类较多时,会使得启动速度变慢。现在流行的设计都是讲“延迟加载”,我们可以在第一次使用的时候才初始化第一个该类对象。
2单例模式实例二(懒汉式)
public class Singleton {
private static Singleton instance;
private Singleton() {
}
public static synchronized Singleton getInstance() { // 对获取实例的方法进行同步
if (instance == null)
instance = new Singleton();
return instance;
}
}
3单例模式实例三(双重同步锁,不推荐可能有问题)
public class Singleton {
private static Singleton instance;
private Singleton (){
}
public static Singleton getInstance(){ //对获取实例的方法进行同步
if (instance == null){
synchronized(Singleton.class){
if (instance == null)
instance = new Singleton();
}
}
return instance;
}
}
这里面的疑问可能是为什么要做两次判断和锁定Singleton.class。
问题一:两个线程同时访问,当线程A的线程B同时访问,都获得instance是null,只有一个线程可以锁定Singleton.class,假设A执行完毕,获得对象,B被唤醒在进行访问时不判断一次,那么就new 出了一个新对象。
问题二:因为是静态方法,所以它只有class可以锁定,没有this锁定。
4.单例模式实例四(使用静态内部类)
public class Singleton {
private Singleton() {
}
public static Singleton getInstance() {
return Inner.s;
}
private static class Inner{
static Singleton s = new Singleton();
}
}
你可能认为这与第一种相同,焦点在于是不是延迟加载,静态内部类对于外部成员只有在第一次调用时才被加载。
破解单例模式(不能破解枚举单例)
单例模式可以通过反射或反序列化进行破解
举例代码如下
Class clazz = (Class) Class.forName("com.singleton.Singleton");
Constructor<Singleton> con = clazz.getDeclaredConstructor(null);
con.setAccessible(true);//跳过权限检查
Singleton s = con.newInstance(null);
System.out.println(s);