文章目录
单例模式
总结:
介绍
保证在整个软件系统中,对某个类对象只能存在一个实例,并且提供一个取得其对象实例的方法。
饿汉式
静态常量方式
实现
构造器私有化,属性位置创建实例的静态变量, 提供静态方获取静态实例。
public class Single {
// 构造器私有化
private Single(){}
// 静态实例
private final static Single instance = new Single();
// 静态方法获取
private static Single getInstance() {
return instance;
}
}
优点:
写法比较简单,在类装载的时候就完成了实例化。避免了线程同步问题。
缺点:
在类装载的时候完成实例化,没有达到Lazy Loading
的效果,如果从始至终没有使用过这个实例,则会造成内存的浪费。
结论:
静态代码块儿方式
这种方式也是在类加载时候进行实例的new
, 因此优点和缺点和静态常量方式一致。
实现
package club.fsociety.singleton;
public class Single2 {
// 构造器私有化
private Single2(){ }
// 静态实例
private static Single2 instance;
// 静态代码快儿
static {
instance = new Single2();
}
// 静态方法获取
private static Single2 getInstance() {
return instance;
}
}
懒汉式
解决Lazy Loading
的问题。
线程不安全的方式
实现:
package club.fsociety.singleton;
public class Single3 {
// 私有构造器
private Single3(){}
// 静态成员
private static Single3 instace;
// 获取实例的方法
private static Single3 getInstace() {
if(null == instace)
instace = new Single3();
return instace;
}
}
优点:
实现了Lazy Loading
。
缺点:
线程不安全,可能多个线程同时判定为未创建,后进行创建,会导致多创建出来几个实例。
结论:
了解其存在的问题,开发中不要使用。
线程安全方式:
实现
使用了同步代码块来修饰获取实例的方法:
package club.fsociety.singleton;
public class Single3 {
// 私有构造器
private Single3(){}
// 静态成员
private static Single3 instace;
// 获取实例的方法
private static synchronized Single3 getInstace() {
if(null == instace)
instace = new Single3();
return instace;
}
}
优点
即解决了饿汉中存在的Lazy Loding
问题,又解决了线程安全问题。
缺点
getInstance
方法频繁调用下会导致效率地下。
结论
在实际开发中不推荐使用。
DoubleCheck
实现
package club.fsociety.singleton;
public class Single4 {
// 私有构造器
private Single4(){}
// 静态成员
private static Single4 instace;
// 获取实例的方法
private static Single4 getInstace() {
if(null == instace) {
synchronized (Single4.class) {
if(null == instace)
instace = new Single4();
}
}
return instace;
}
}
优点
  即解决了Lazy Loading
和 线程安全问题,又避免每次getInstance
的时候都执行一遍同步代码块儿。
缺点
 
结论:
强烈推荐使用。
静态内部类方式
实现方式
外部类被装载的时候,静态内部类不会被装载。当调用外部类获取静态内部类方法时候再装载静态内部类,且静态内部类被装载后会初始化静态代码,且线程安全。这样既能解决线程安全问题,也能解决Lazy Loading
问题。
package club.fsociety.singleton;
public class Single5 {
// 私有化的构造
private Single5(){}
// 静态内部类
private static class Single5Instance {
private static final Single5 instance = new Single5();
}
// 获取实例方法
public static Single5 getInstance() {
return Single5Instance.instance;
}
}
优点:
解决线程安全,和LazyLaoding
问题,且效率高。
结论
推荐使用。
枚举
实现方式:
JDK1.5
中添加的枚举来实现单例模式,因为枚举当中的每个枚举元素本声就是自身的一个实例的单例,刚好可以直接借助来实现单例模式。
public enum Single6 {
INSTANCE;
public void method() {
System.out.println("这是一个实例方法");
}
}
优点
能避免多线程同步问题,而且还能防止反序列化重新创建的对象。其为最推荐的方式。