`
lovesailing
  • 浏览: 36563 次
  • 性别: Icon_minigender_1
  • 来自: 陕西
社区版块
存档分类
最新评论

Singleton(单例模式)探索

阅读更多

 


 Singleton, 单例模式: 顾名思义,就是只有一个实例。常见的实现方法有以下几种.

 

1. 懒汉

 

  

public class Singleton{  
  
 private static Singleton instance = null;  
     
 private Singleton(){  
    
 }  
    
 public static Singleton getInstance(){  
    if(instance == null){  
       instance = new Singleton();  
    }  
    return instance;  
 }  
}  

 

这种实现方式:

 

1. 非线程安全。并发情况下,可能有多个线程进入if语句块,从而创建了多个实例。

2. 节约内存空间。只有在调用getInstance()的时候才分配对象的空间。

3. 浪费时间。每次调用都要判断instance是否为空。

4. 初始化的时候比较快,而运行时比较慢。

5. 体现了延迟加载的思想。

6. 非线程安全问题,可以通过使用synchronized关键字来处理(后面还会讨论)

 

 

 

2. 饿汉

 

  

public class Singleton{  
  
 private static final Singleton instance = new Singleton();  
     
 private Singleton(){  
    
 }  
    
 public static Singleton getInstance(){  
    
    return instance;  
 }  
}  

 

这种实现方式:

1. 线程安全的。因为类加载的时候,instance对象只被初始化了一次,利用JVM类加载机制来保证线程安全。

2. 牺牲空间。加载类的时候,无论是否使用该类,都分配了内存空间。

3. 初始化的时候稍慢,但是运行时快。

4. 体现了缓存思想。

 

 

 

 

3. 双重检查加锁机制(对比并优化懒汉方法

 

public class Singleton {
    private volatile static Singleton instance = null;

    private Singleton(){

    }

    public static Singleton getInstance(){
        //先检查实例是否存在,如果不存在才进入下面的同步块
        if(instance == null){
        //同步块,线程安全的创建实例
            synchronized (Singleton.class) {
           //再次检查实例是否存在,如果不存在才真正的创建实例
               if(instance == null){
                   instance = new Singleton();
               }
            }
        }
        return instance;
     }
}
 

 

这种实现方式:

1. 线程安全。

2. 加快运行速度。只是第一次创建实例的时候同步,以后都不用同步了。

3. 比在懒汉方式中加入synchronized方法效率高:(如下)

4. volatile修饰的变量值,将不会被本地线程缓存,所有对该变量的读写都是直接操作共享内存。

5. volatile关键字屏蔽掉了JVM中的一些必要的代码优化,所以可能降低一些运行效率(没有验证)。

public static synchronized getInstance(){
     
}

 

4. 更优解决方案

 

public class Singleton {  
   
     private static class Holder {  
         private static final Singleton instance = new Singleton();  
     }  
   
     private Singleton() {  
     }  
   
     public static Singleton getInstance() {  
         return Holder.instance;  
     }  
 }  

 

 

这种实现方法:

1. 使用静态内部类和缺省同步机制实现。

2. 缺省同步机制是指:JVM隐含的执行的同步,这里指静态初始化器(在静态字段或者static{}上的初始化     器)初始化的时候。

3. 类加载的时候并不会像饿汉一样初始化对象,而是在getInstance被调用之后才会。而且JVM保证了线程安 全问题。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics