面试题(二)单例模式

一、恶汉式

  直接实例化恶汉式(简洁直观)

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 }

 

转载于:https://www.cnblogs.com/in-the-game-of-thrones/p/11396364.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值