一、枚举实现单例
public enum Application {
INSTANCE;
public void sayOK() {
System.out.println("OK....");
}
}
优点:天生能避免线程同步问题,而且还能防止反序列化重新创建新对象。
二、静态内部类实现单例
public class Application {
//构造器私有化,外部不能new
private Application() {}
//定义对象变量,注意使用的volatile关键字
private static volatile Application instance;
//静态内部类
//懒加载可用,在Application加载的时候SingleInstance类不会加载,只有在getInstance的时候才被装载
private static class SingleInstance {
private static final Application INSTANCE = new Application();
}
//获取值
public static Application getInstance() {
return SingleInstance.INSTANCE;
}
}
优点:避免了线程不安全,且可以实现懒加载,效率高
三、懒汉模式双重检查实现单例
public class Application {
//构造器私有化,外部不能new
private Application() {}
//定义对象变量,注意使用的volatile关键字
private static volatile Application instance;
//对外提供get方法,获取这个类,双重检查
//解决了线程不安全,懒加载、效率低这三个问题
public static Application getInstance() {
if(instance == null) {
synchronized (Application.class) {
if(instance == null) {
instance = new Application();
}
}
}
return instance;
}
}
优点:线程安全、懒加载、效率高
四、饿汉模式实现单例
public class Application {
//构造器私有化,外部不能new
private Application() {}
//在本类中创建对象
private final static Application instance = new Application();
//对外提供get方法,获取这个类
public static Application getInstance() {
return instance;
}
}
优点:线程安全,程序启动是就实例化
缺点:如果该类没有被调用,造成内存空间浪费。如果该类是一个重类,增加程序启动时间。
五、饿汉模式静态代码块
public class Application {
//构造器私有化,外部不能new
private Application() {}
//定义对象变量
private final static Application instance;
//静态代码块创建实例
static {
instance = new Application();
}
//对外提供get方法,获取这个类
public static Application getInstance() {
return instance;
}
}
优缺点和第四一样,只是换种写法
六、懒汉模式(线程不安全写法)
public class Application {
//构造器私有化,外部不能new
private Application() {}
//定义对象变量
private static Application instance;
//对外提供get方法,获取这个类
public static Application getInstance() {
if(instance == null) {
//这里导致线程不安全,第一个线程进来为空,然后第一个线程去创建对象;当第二个线程进来的时候,
//第一个线程可能还没有创建完成,因此第二个线程有进入了if内,导致再次创建对象
instance = new Application();
}
return instance;
}
}
优点:解决了不能懒加载问题
缺点:线程不安全
七、懒汉模式(线程安全写法)
public class Application {
//构造器私有化,外部不能new
private Application() {}
//定义对象变量
private static Application instance;
//对外提供get方法,获取这个类,同步方法,解决线程安全
public synchronized static Application getInstance() {
if(instance == null) {
instance = new Application();
}
return instance;
}
}
优点:线程安全,实现懒加载
缺点:效率低
总结:
在工作中推荐使用:枚举、静态内部类、懒汉模式双重检查。别的几种或多或少都有一定的缺点,视情况而定。