阶段一/Java单例模式/Java单例模式

目录

一、单例模式的定义和作用

代码实现方案

单例模式优缺点总结

关于单例模式的一些问题的说明


 

 

一、单例模式的定义和作用

设计模式:是软件开发人员在软件开发过程中面临的一般问题的解决方案

目的

  • 使得类的一个对象成为该类系统中的唯一实例

定义

  • 一个类有且仅有一个实例,并且自行实例化想整个系统提供

要点

  • 某个类只能有一个实例
  • 必须自行创建实例
  • 必须自行向整个系统提供这个实例

实现:

  • 只提供私有的构造方法(私有构造方法,类外无法通过new关键字来实例化对象)
  • 含有一个该类的静态私有对象(static刚好可以满足有且仅有)
  • 提供一个静态的公有方法用于创建、获取静态私有对象

代码实现方案

  • 饿汉式:对象创建过程中实例化
  • 懒汉式:静态共有方法中实例化

饿汉式实现方式,用慕课网的作业来说明

构造方法中有一条打印语句,实例化了多少个对象就会输出几次,但是我们发现最终只有一条打印输出,这就是static关键字的作用,在类加载的时候执行private static Earth instance = new Earth();语句,该语句还会负责实例化对象(地球诞生就是这时候打印的),并让instance指向实例化出来的对象,static属性只会在类加载的时候加载,也即该语句只会被调用一次。加之构造方法是私有的,在类外无法进行对象的实例化,在类内部也只有一个实例化语句还是static修饰的,故只会有一个对象。

//饿汉式:创建对象实例的时候直接初始化,空间换时间
public class Earth {
    //定义私有构造方法,并在构造方法中打印输出“地球诞生”
    private Earth(){
        System.out.println("地球诞生");
    }
    //定义私有静态类对象并完成实例化
    private static Earth instance = new Earth();
    //定义公有静态方法返回类内的私有静态对象
    public static Earth getInstance(){
        return instance;
    }
}

我们来看看测试类,以及测试的输出

public class EarthTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        System.out.println("第一个地球创建中。。。。");
        Earth one = Earth.getInstance();

        System.out.println("第二个地球创建中。。。。");
        Earth two = Earth.getInstance();

        System.out.println("问:两个地球是同一个么?");
        System.out.println(one);
        System.out.println(two);
        System.out.println(one == two);
    }
}

输出,从输出可以看出,构造方法只执行了一次,且从后面one和two的打印来看指向的是同一个对象。

第一个地球创建中。。。。
地球诞生
第二个地球创建中。。。。
问:两个地球是同一个么?
com.imooc.earth.Earth@6e0be858
com.imooc.earth.Earth@6e0be858
true

下面我们来看看懒汉式

这边与饿汉式的区别是类内实例对象创建时并不直接初始化,直到第一次调用get方法时,才会完成初始化操作,然后我们通过get方法的判断语句确保只有一个实例对象。

// 懒汉式:类内实例对象创建时并不直接初始化,直到第一次调用get方法时,才会完成初始化操作
// 时间换空间
public class SingletonTwo {
    //1、创建私有构造方法
    private SingletonTwo(){
        System.out.println("我是SingletonTwo的构造方法");
    }

    //2、创建静态的该类实例对象
    private static SingletonTwo instance = null;

    //3、创建开放的静态方法提供实例对象
    public static SingletonTwo getInstance(){
        // 精髓,这边保证了只有一个实例
        if(instance == null)
            instance = new SingletonTwo();
        return instance;
    }
}
public class SingletonTest {
    public static void main(String[] args){

        SingletonTwo singletonTwoOne = SingletonTwo.getInstance();
        System.out.println(singletonTwoOne);

        SingletonTwo singletonTwoTwo = SingletonTwo.getInstance();
        System.out.println(singletonTwoTwo);

        System.out.println(singletonTwoOne == singletonTwoTwo);
    }
}

 

输出,从输出我们依旧可以看出,他们指向的是同一块内存空间。

我是SingletonTwo的构造方法
com.imooc.singleton.SingletonTwo@61bbe9ba
com.imooc.singleton.SingletonTwo@61bbe9ba
true
  • 饿汉式线程安全;懒汉式存在线程风险

懒汉式线程风险解决方法

  • 同步锁
  • 双重教验锁
  • 静态内部类
  • 枚举

等方式来保证操作时的线程唯一。

单例模式优缺点总结

单例模式优点

  • 在内存中只有一个对象,节省内存空间
  • 避免频繁的创建销毁对象,提高性能
  • 避免对共享资源的多重占用

单例模式缺点

  • 扩展比较困难
  • 若实例化的对象长期不利用,系统将默认为垃圾进行回收,造成对象状态丢失

单例模式使用场景

  • 创建对象时占用资源过多,但同时又需要用到该类对象
  • 对系统内资源要求统一读写,如读写配置信息
  • 当多个实例存在可能引起程序逻辑错误,如号码生成器

关于单例模式的一些问题的说明

所谓单例模式只能有一个对象,指无论应用该类型产生多少对象,都是指向唯一的堆空间。

关于getInstance方法前的static的说明,对于单例模式,需要在类外能在无需产生对象实力的情况下,完成这个方法的调用,因此该方法需要设置为static,这样就可以在类外通过类名调用。否则必须先实例化对象,通过对象名调用,但是由于构造方法的private,在类外无法通过new关键字实例化对象。产生矛盾。

关于final

  • 懒汉式不能加入final,因为final修饰的静态成员,若定义时未初始化,不能在类方法中进行实例初始化。
  • 饿汉式,对类实例只涉及创建和返回,则可以加入;若还包括其他功能,如资源回收等,加入final有可能会影响程序功能实现。

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值