- 简单实用的方法
public class Singleton1 {
private static final Singleton1 INSTANCE = new Singleton1();
private Singleton1() {
System.out.println("init");
}
public static Singleton1 getInstance() {
return INSTANCE;
}
}
- jvm 保证了java 初始化一次class
- static 又保证了类在被加载完后立马初始化static 变量。
- 例如vertx框架中 vertx.vert 就是这么实现的单例。
- 缺点:不管用不用都会被实例化(个人看法写出来就是给我用的,还能加加快真正使用时的实例化时间,多好)
- lazy加载模式
public class Singleton2 {
private static Singleton2 INSTANCE ;
private Singleton2() {
System.out.println("init");
}
public static Singleton2 getInstance() {
if(INSTANCE==null){
INSTANCE = new Singleton2();
}
return INSTANCE;
}
}
- 懒加载模式 需要的时候再去初始化他,但是这样并不是线程安全的
- 解决方案方法上加synchronized锁即可,但是效率会变低。
- 双重判断锁
public class Singleton3 {
private static volatile Singleton3 INSTANCE; // volatile 防止指令重排序
private Singleton3() {
System.out.println("init");
}
public static Singleton3 getInstance() {
if (INSTANCE == null) {
synchronized (Singleton3.class) {
if (INSTANCE == null) {
INSTANCE = new Singleton3();
}
}
}
return INSTANCE;
}
}
- 静态内部类初始化
public class Singleton4 {
private Singleton4() {
System.out.println("init");
}
public static Singleton4 getInstance() {
return SingletonHolder.INSTANCE;
}
private static class SingletonHolder{
private static final Singleton4 INSTANCE = new Singleton4();
}
}
- 利用jvm 特性起java 只会初始化 Singleton4,不会初始化内部类,等真的要用的时候才会去初始化对象。
- 枚举类保证单例
public enum Singleton5 {
INSTANCE;
}