单例模式是我们经常使用的一种设计模式,那么让我们自己来设计一种单例模式的话,我们该如何设计呢??
设计的方式有很多种,我们依次来看一下:
首先是第一种:
1 /** 2 * 简单的方式:在并发执行的时候可能存在多个实例 3 * 4 * @author cuibin 5 * @create 2017-08-30 20:38 6 **/ 7 public class Singleton1 { 8 9 private static Singleton1 INSTANCE; 10 11 private Singleton1(){} 12 13 public static Singleton1 getInstance(){ 14 if(INSTANCE == null){ 15 INSTANCE = new Singleton1(); 16 } 17 return INSTANCE; 18 } 19 }
第一种思路是比较简单的,通过判断来确定是否创建实例,但是有个致命的问题,在高并发时,当两个或几个请求同时到达时,还是会创建多个实例,怎么解决呢,我们来看第二种:
1 ** 2 * 公共域方式 简单 3 * @author cuibin 4 * @create 2017-08-30 20:47 5 **/ 6 public class Singleton2 { 7 8 public static final Singleton2 INSTANCE = new Singleton2(); 9 10 private Singleton2(){}; 11 12 }
第二种采用公共域的方式,有效的解决了并发状态下多个实例的问题,但是,问题又出现了,我们不能够在实例中添加逻辑,gg了,我们来看第三种:
1 /** 2 * 工厂化方式,可以在实例过程中添加逻辑 3 * 4 * @author cuibin 5 * @create 2017-08-30 20:49 6 **/ 7 public class Singleton3 { 8 9 private static final Singleton3 INSTANCE = new Singleton3(); 10 11 12 private Singleton3(){} 13 14 public static Singleton3 getInstance(){ 15 return INSTANCE; 16 } 17 }
第三种看起来非常完美了,但它还不是最好的,我们来看最好的写法:
1 /** 2 * 枚举类方式 最佳实践 3 */ 4 public enum Singleton4 { 5 6 INSTANCE; 7 8 public static void say(String str){ 9 System.out.println("hello " + str); 10 } 11 }
通过枚举类的方式,最佳实践。接下来我们来测试一下,看是否能真正实现单例:
1 /** 2 * @author cuibin 3 * @create 2017-08-30 20:54 4 **/ 5 public class TestSingleton { 6 7 public static void main(String[] args) { 8 9 System.out.println("Singleton1" + Singleton1.getInstance()); 10 System.out.println("Singleton1" + Singleton1.getInstance()); 11 12 System.out.println("Singleton2" + Singleton2.INSTANCE); 13 System.out.println("Singleton2" + Singleton2.INSTANCE); 14 15 System.out.println("Singleton3" + Singleton3.getInstance()); 16 System.out.println("Singleton3" + Singleton3.getInstance()); 17 18 System.out.println("Singleton4" + Singleton4.INSTANCE); 19 System.out.println("Singleton4" + Singleton4.INSTANCE); 20 Singleton4.INSTANCE.say("cuibin"); 21 } 22 }
我们来看控制台输出:
以上就是设计单例的四种方式。