设计模式--单例模式

单例模式

Java工程源码

类图

这里写图片描述


定义:
确保某一个类只有一个实例,而且自行实例化并向整个系统提供这个实例


优点:
- 内存中仅一个实例,故减少了内存开支
- 由于只生成一个实例,故减少了系统性能开销(如读取配置,产生依赖对象等,利用常驻内存的方式,仅生成一个对象
- 可以避免对资源的多重占用(如只有一个实例存在,避免对同一资源文件同时写操作)

缺点:
- 单例模式没有接口,扩展困难
- 与单一职责原则有冲突


使用场景
- 要求生成唯一序列号的环境
- 整个项目需要一个共享访问点或共享数据(如web页面的计数器)
- 创建一个对象需要消耗的资源过多时


懒汉,线程不安全

public class Singleton {  
    private static Singleton instance;  
    private Singleton (){}  

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

这种方法是lazy load,但是致命的问题就是线程不安全。比如我们有2个线程同时执行getInstance方法,并且同时做了 if (instance == null) 的判断。这时2个线程都认为instance没有初始化,然后它们同时初始化并返回,最后返回了不同的实例,并不是我们想要的同一个对象。


懒汉,线程安全

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

这种写法就上一种写法加上同步锁,但是效率很低,每次调用方法都有锁操作。


饿汉

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

没有lazy load


静态内部类(推荐)

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

这种方式是java编程思想一书中提到的方法,利用ClassLoader机制保证初始化instance时只有一个线程。


枚举

public enum Singleton {
    INSTANCE;
    public void doSomething(){ 
    }
}

双重校验锁

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

JDK1.5之前由于jvm方法执行顺序重排,导致依然无法实现单例,具体可以参阅Java编程思想,JDK1.5只有正常。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值