饿汉式
public class Single1 {private static Single1 singleOne = new Single1();private Single1(){}public static Single1 getSingleOne() {return singleOne;}}
-
懒汉式
public class Single2 {private static Single2 single2;private Single2(){}public static Single2 getSingle2() {if (single2 == null) {single2 = new Single2();}return single2;}}
解决了饿汉式的问题,但是在多线程环境下使用依然可能创建多个对象
懒汉式加锁
public class Single3 {private static volatile Single3 single3;private Single3(){}public static synchronized Single3 getSingle3() {if (single3 == null) {single3 = new Single3();}return single3;}}
解决了懒汉式中线程不安全的问题,但是在方法中加锁退变成了单线程执行的模式
双重检查锁形式
public class Single4 {private static volatile Single4 single4;private Single4(){}public static Single4 getSingle4() {// 第一个判断是为了避免所有的线程都直接进入 同步代码块if (single4 == null) {synchronized (Single4.class) {// 如果没有该判断,可能多个线程都进入第一个if块,虽然同步块只有一个线程可以执行,但是已经进入第一个if块的代码还是可以执行new 命令,// 这样就不能实现单例if (single4 == null) {single4 = new Single4();}}}return single4;}}
解决懒汉式的问题,这种方式已经算是比较完美的了,只是不能防止反序列化的形式来创建对象
使用内部类的形式创建单例
public class Single6 {private Single6() {}private static class InnerSingle6 {private static Single6 single6 = new Single6();}public static Single6 getSingle6() {return InnerSingle6.single6;}}
使用枚举的形式来创建单例
public class Single5 {private Single5(){}private enum Single5Enum {INSTANCE;private Single5 single5;Single5Enum() {this.single5 = new Single5();}}public static Single5 getSingle5() {return Single5Enum.INSTANCE.single5;}}
枚举是不能使用 new 关键字来创建对象的,所以可以防止使用反序列化的形式来创建对象
- 由于枚举中的对象在一开始就创建好了,所以在多线程环境下使用也是线程安全的
