设计模式——单例模式

单例的目的是为了保证运行时Singleton类只有唯一的一个实例,最常用的地方比如拿到数据库的连接,Spring的中创建BeanFactory这些开销比较大的操作,而这些操作都是调用他们的方法来执行某个特定的动作。主要有以下两种实现方式:

饥饿模式

public class Singleton {  

    private Singleton() {}  
    private static Singleton instance =  new Singleton(); 

    public static Singleton getInstance() {  
        return instance;  
    }  
} 
/*这会带来潜在的性能问题:如果这个对象很大,在没有使用这个对象之前,就把它加载到了内存中去是一种巨大的浪费。但该模式能保证多线程时的线程安全*/

懒汉模式

public class Singleton {  

    private Singleton() {}  

    private static Singleton instance = null;  

    public static Singleton getInstance() {  
        if(instance == null) {  
            instance = new Singleton();  
        }  
        return instance;  
    }  
}  
/*这也会有问题,如果是多线程的情况下,如果两个线程同时执行到了if(instance == null)就都会创建一个对象
所以懒汉式只适用于单线程的情况*/

如果多线程情况下,我们又不想用饿汉式,该怎么办呢?我们可以使用synchronized 来同步,并使用双重检查锁和volatile保证可能出现的问题:
双重检查锁定具体分析见:https://blog.csdn.net/zcl_love_wx/article/details/80758162

public class Singleton{   
    // 静态属性,volatile保证可见性和禁止指令重排序
    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;   
    }   
}

上面的synchronized 同步性能不够好。可以改为如下的方式:

目前最优的方式:静态内部类

public class Resource{     
    private Resource(){}

    private static class ResourceHolder {    
        // 静态内部类里其实也是饿汉模式 
        public static Resource resource = new Resource();     
    }     

    public static Resource getResource() {     
        return ResourceHolder.resource;     
    }     

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值