单例设计模式

解决问题:保证一个类在内存中的对象唯一性

适用环境:对于多个程序适用同一个配置信息对象时,就需要保证该对象的唯一性

 

单例模式特点(如何保证对象唯一性?)

1、不允许其他程序用new创建该类对象

2、在该类创建一个本类实例。

3、对外提供一个方法让其他程序可以获取该对象

 

步骤:

1、私有化该类构造函数

2、通过new在本类中创建一个本类对象(私有静态化)

3、定义一个公有静态方法,将创建的对象返回

 

饿汉式:

1、类一加载,对象就已经存在了。

2、线程安全

 

public class Single{
  private static Single single = new Single();

  private Single(){}
  
  public static Single getInstance(){
     return single;
   }
}
     

 

 

懒汉式:

1、类加载进来,没有对象,只有调用了getInstance方法时,才会创建对象。(延迟加载)

2、线程不安全(需要自己实现)

  不安全的原因:

假设开始线程0进入,判断instance为空,在将要创建实例时,cpu切换,

线程1又进来了,同样instance为空 创建了实例,这是cpu切换回来到0线程,继续创建实例

可见,经过分析共创建了 两个实例,还谈什么单例。

 

public class Single{
    private static Single single=null;

    private Single(){}
    
    private static Single getInstance(){
        if(s==null)
            s = new Single();
         return s;
    }
}            

 

但是以上懒汉式单例的实现没有考虑线程安全问题,它是线程不安全的,并发环境下很可能出现多个Singleton实例,要实现线程安全,有以下三种方式,都是对getInstance这个方法改造,保证了懒汉式单例的线程安全。

 

1、在getInstance方法上加同步

public static synchronized Singleton getInstance() {  
         if (single == null) {    
             single = new Singleton();  
         }    
        return single;  
}  

 

2、双重检查锁定

public static Singleton getInstance() {  
        if (singleton == null) {    
            synchronized (Singleton.class) {    
               if (singleton == null) {    
                  singleton = new Singleton();   
               }    
            }    
        }    
        return singleton;   
    }  

 

3、静态内部类

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

 

第三种方法最好,既实现了线程安全,有避免了同步带来的性能影响。

 

posted @ 2018-05-25 00:55  snoopy666  阅读(59)  评论(0)    收藏  举报