一、恶汉式
直接实例化恶汉式(简洁直观)
1 public class Test { 2 //构造私有化 3 private Test(){} 4 //创建单列对象,提供给外界 5 public static final Test INSTANCE = new Test(); 6 }
枚举式(最简洁)
1 /** 2 * 枚举,表示该类型的对象是有限的几个!!! 3 * 枚举类型的构造器全部都是私有化的。 4 * 枚举中重写了toString方法,所以打印出来的就是重写后的名称 5 * 为此,我们就可以限定一个,于是就成了单列了。 6 */ 7 public enum Test { 8 //定义 9 INSTANCE 10 }
静态代码块恶汉式(适合复杂实例化)
1 /** 2 * 静态代码块恶汉式(适合复杂实例化) 3 */ 4 public class Test { 5 //声明变量 6 public static final Test INSTANCE; 7 static{ 8 INSTANCE = new Test(); 9 } 10 //构造私有化 11 private Test(){} 12 }
二、懒汉式
双重if判断
1 /** 2 * 静态代码块恶汉式(适合复杂实例化) 3 */ 4 public class Test { 5 //声明变量 6 private static Test INSTANCE; 7 //构造私有化 8 private Test(){} 9 10 //外界方法 11 public static Test getINSTANCE(){ 12 if(INSTANCE == null){ 13 try {//模拟线程阻塞 14 Thread.sleep(1000); 15 } catch (InterruptedException e) { 16 e.printStackTrace(); 17 } 18 synchronized(Test.class){//双重if判断 19 try {//模拟线程阻塞 20 Thread.sleep(1000); 21 } catch (InterruptedException e) { 22 e.printStackTrace(); 23 } 24 if (INSTANCE == null){ 25 INSTANCE = new Test(); 26 } 27 } 28 } 29 return INSTANCE; 30 } 31 } 32 //测试 33 import java.util.concurrent.*; 34 35 public class MAINTest { 36 public static void main(String[] args) { 37 //Callable,在任务执行完毕之后得到任务执行结果。 38 Callable<Test> testCallable = new Callable<Test>() { 39 @Override 40 public Test call() throws Exception { 41 return Test.getINSTANCE(); 42 } 43 }; 44 //newFixedThreadPool线程池,创建5个线程 45 ExecutorService executorService = Executors.newFixedThreadPool(5); 46 Future<Test> submit1 = executorService.submit(testCallable); 47 Future<Test> submit2 = executorService.submit(testCallable); 48 Future<Test> submit3 = executorService.submit(testCallable); 49 Future<Test> submit4 = executorService.submit(testCallable); 50 Future<Test> submit5 = executorService.submit(testCallable); 51 try { 52 Test test1 = submit1.get(); 53 Test test2 = submit2.get(); 54 Test test3 = submit3.get(); 55 Test test4 = submit4.get(); 56 Test test5 = submit5.get(); 57 System.out.println(test1); 58 System.out.println(test2); 59 System.out.println(test3); 60 System.out.println(test4); 61 System.out.println(test5); 62 //关闭线程池 63 executorService.shutdown(); 64 } catch (InterruptedException e) { 65 e.printStackTrace(); 66 } catch (ExecutionException e) { 67 e.printStackTrace(); 68 } 69 } 70 }
静态内部类
1 /** 2 * 静态代码块恶汉式(适合复杂实例化) 3 */ 4 public class Test { 5 //构造私有化 6 private Test(){} 7 8 /** 9 * 静态内部类 10 * 它不会自动随着外部类的加载与初始化二初始化,它是单独的加载与初始化 11 * 外部类对象是在内部类加载与初始化时,创建的,因此是线程安全的。 12 * 直接在内部类中构造一个私有的外部类对象 13 */ 14 private static class Inner{ 15 private static final Test INSTANCE = new Test(); 16 } 17 18 //外界方法 19 public static Test getINSTANCE(){ 20 //直接通过内部类点外部类对象返回给外界 21 return Inner.INSTANCE; 22 } 23 }