C++11多线程学习:单例模式

两种简单单例

饿汉式

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

懒汉式

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

这里显然有线程安全的问题,可能创建多个类实例出来,使用synchronize锁住整个方法是有效但是低效的,所以目前有double-checked locking模式,代码如下:

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

这里出错的根本原因在于:Java指令中指令重排序引起,也就是说instance = new Singleton();语句是分三步执行的。为Singleton实例分配空间,然后直接赋值给instance成员,然后再去初始化这个Singleton实例。(即先赋值指向了内存地址,再初始化)
具有以下三种改进策略:

  1. 使用饿汉式
  2. 使用volatile
public class Singleton {  
    private static volatile Singleton instance;  

    private Singleton() {  
    }  

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

3.延迟初始化内部类

public class Singleton {  
    private static class InstanceHolder {  
        public static Singleton instance = new Singleton();  
    }  

    private Singleton() {  
    }  

    public static Singleton getInstance() {  
        return InstanceHolder.instance;  
    }  
}  

C++和DCLP的风险

猜你喜欢

转载自blog.csdn.net/weixin_42013750/article/details/82425597