单例模式

单例模式分为懒汉式和饿汉式

  目的:只创建一个对象实例

  需要将构造器私有化,防止通过new的方式创建对象实例

懒汉式:

  延迟加载  -->   需要用到的时候,先去判断该对象实例是否为null,如果为null才会重新创建

  缓存思想  -->  不为null则直接使用已缓存的对象实例

  线程不安全

 1 public class Singleton {
 2     private static Singleton singleton;
 3 
 4     private Singleton() {}
 5 
 6     public static Singleton getInstance(){
 7         if(singleton == null){
 8             singleton = new Singleton();
 9         }
10         return singleton;
11     }
12 }

当该对象实例不一定用到时,可以使用懒汉模式(延迟加载)

 

懒汉式(线程安全,synchronized):

 1 public class Singleton {  
 2 
 3     private static Singleton instance;  
 4 
 5     private Singleton (){}  
 6 
 7     public static synchronized Singleton getInstance() {  
 8         if (instance == null) {  
 9             instance = new Singleton();  
10         }  
11         return instance;  
12     }  
13 }

效率低(不管对象实例是否为null,都会上锁)

 

懒汉式(线程安全,双重检查加锁):

 1 public class Singleton {  
 2 
 3     private volatile static Singleton singleton;  
 4 
 5     private Singleton (){}  
 6 
 7     public static Singleton getSingleton() {  
 8         if (singleton == null) {  
 9             synchronized (Singleton.class) {  
10                 if (singleton == null) {  
11                     singleton = new Singleton();  
12                 }  
13             }  
14         }  
15         return singleton;  
16     }  
17 }

volatile:可见性,其它线程可见,直接读取主内存中的数据,使其线程获取的总是最后修改后的值

先检查对象实例是否为null,不为null就直接返回,为null才进入同步锁;

此时再次检查实例对象是否为null,为null才创建。

 

饿汉式:

  线程安全

  空间换时间

1 public class Singleton {  
2     private static Singleton instance = new Singleton();  
3 
4     private Singleton (){}  
5 
6     public static Singleton getInstance() {  
7         return instance;  
8     }  
9 }

当对象实例一定会用到时,可以使用饿汉模式(类加载时就创建对象实例)

 

静态内部类实现单例:

  线程安全

  延迟加载  

 1 public class Singleton {  
 2 
 3     private static class SingletonHolder {  
 4         private static Singleton INSTANCE = new Singleton();  
 5     }  
 6 
 7     private Singleton (){}  
 8 
 9     public static final Singleton getInstance() {  
10         return SingletonHolder.INSTANCE;  
11     }  
12 }

 

枚举实现单例:

  线程安全

1 enum SingleEnum{
2     //枚举元素 SINGLE_ENUM 默认就是该对象一个实例
3     SINGLE_ENUM;
4 }

 

利用枚举和map集合实现只创建 两个 对象实例

 1 public class SingleNumControl {
 2     private int num = 0;
 3     private Map<Integer,SingleNumControl> map = new HashMap<>();
 4 
 5     private SingleNumControl() {}
 6 
 7     public SingleNumControl getInstance(){
 8         SingleNumControl single = map.get(num);
 9         if(single == null){
10             single = new SingleNumControl();
11             map.put(num,single);
12         }
13         num++;
14         if(num >= 2){
15             num = 0;
16         }
17         return single;
18     }
19 
20     public static void main(String[] args) {
21         SingleNumControl singleNumControl = new SingleNumControl();
22         for (int i = 0; i < 8; i++) {
23             System.out.println(singleNumControl.getInstance());
24         }
25     }
26 
27 }

 

posted @ 2019-07-30 19:46  搬块砖可以吗  阅读(144)  评论(0)    收藏  举报