Java基础(十六)-单例模式

单例模式

简介

单例模式,是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中,应用该模式的类一个类只有一个实例。即一个类只有一个对象实例

保证全局过程中只存在一个唯一实例的模式

单例模式的要点有三个:一是某个类只能有一个实例;二是它必须自行创建这个实例;三是它必须自行向整个系统提供这个实例。

优缺点

优点:

  1. 实例控制单例模式会阻止其他对象实例化其自己的单例对象的副本,从而确保所有对象都访问唯一实例。
  2. 灵活性因为类控制了实例化过程,所以类可以灵活更改实例化过程。

缺点:

  1. 开销虽然数量很少,但如果每次对象请求引用时都要检查是否存在类的实例,将仍然需要一些开销。可以通过使用静态初始化解决此问题。
  2. 可能的开发混淆使用单例对象(尤其在类库中定义的对象)时,开发人员必须记住自己不能使用new关键字实例化对象。因为可能无法访问库源代码,因此应用程序开发人员可能会意外发现自己无法直接实例化此类。
  3. 对象生存期不能解决删除单个对象的问题。在提供内存管理的语言中(例如基于.NET Framework的语言),只有单例类能够导致实例被取消分配,因为它包含对该实例的私有引用。在某些语言中(如 C++),其他类可以删除对象实例,但这样会导致单例类中出现悬浮引用

实现单例模式的方式

1.饿汉式单例(立即加载方式)

复制代码
// 饿汉式单例
public class Singleton1 {
    // 私有构造
    private Singleton1() {}

    private static Singleton1 single = new Singleton1();

    // 静态工厂方法
    public static Singleton1 getInstance() {
        return single;
    }
}

2.懒汉式单例(延迟加载方式)

复制代码
// 懒汉式单例
public class Singleton2 {
// 私有构造 private Singleton2() {}
private static Singleton2 single = null;
public static Singleton2 getInstance() { if(single == null){ single = new Singleton2(); } return single; } }
复制代码

 

该示例虽然用延迟加载方式实现了懒汉式单例,但在多线程环境下会产生多个single对象,如何改造请看以下方式:

使用synchronized同步锁

复制代码
public class Singleton3 {
    // 私有构造
    private Singleton3() {}

    private static Singleton3 single = null;

    public static Singleton3 getInstance() {
        
        // 等同于 synchronized public static Singleton3 getInstance()
        synchronized(Singleton3.class){
          // 注意:里面的判断是一定要加的,否则出现线程安全问题
            if(single == null){
                single = new Singleton3();
            }
        }
        return single;
    }
}
复制代码

在方法上加synchronized同步锁或是用同步代码块对类加同步锁,此种方式虽然解决了多个实例对象问题,但是该方式运行效率却很低下,下一个线程想要获取对象,就必须等待上一个线程释放锁之后,才可以继续运行。


饿汉式相对懒汉式来说耗费内存。懒汉式相对饿汉式而言,存在线程安全问题。

相关资料:

http://www.runoob.com/design-pattern/singleton-pattern.html

https://www.cnblogs.com/garryfu/p/7976546.html

https://www.cnblogs.com/Ycheng/p/7169381.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值