优秀的编程知识分享平台

网站首页 > 技术文章 正文

每天一个java知识点之单例模式(java单例模式是什么意思)

nanyue 2024-09-07 16:43:52 技术文章 12 ℃

设计模式(Design pattern)

设计模式代表了最佳的实践,通常被有经验的面向对象的软件开发人员所采用。设计模式是软件开发人员在软件开发过程中面临的一般问题的解决方案。这些解决方案是众多软件开发人员经过相当长的一段时间的试验和错误总结出来的。简单一句话就是踩在巨人的肩膀上干活。
JAVA一共有23种设计模式,我们今天首先来学其中一种:单例设计模式

单例设计模式

单例模式可能是大多数开发人员使用最多的一种设计模式,常见的Spring默认创建的bean就是单例模式的。

单例模式有很多好处,比如节约系统存空间,控制资源使用等。

那我们来看看重点,单例模式的最总要的原理是确保对象只有一个。

就是我们说的确保一个类在内存中的对象只有一个。

RunTime就是典型的单例设计,我们通过对RunTime类的分析,一窥究竟。

RunTime源码解析

 /**
 * Every Java application has a single instance of class
 * <code>Runtime</code> that allows the application to interface with
 * the environment in which the application is running. The current
 * runtime can be obtained from the <code>getRuntime</code> method.
 * <p>
 * An application cannot create its own instance of this class.
 *
 * @author  unascribed
 * @see     java.lang.Runtime#getRuntime()
 * @since   JDK1.0
 */
public class Runtime {
	//1.创建静态的全局唯一的对象
private static Runtime currentRuntime = new Runtime();

//2.私有化构造方法,不让外部来调用
    /** Don't let anyone else instantiate this class */
    private Runtime() {}
    
	//3.通过自定义的静态方法获取实例
    public static Runtime getRuntime() {
        return currentRuntime;
}
}

通过分析,底层的实现方式分为三步;

1、本类的构造函数私有化,原因是为了防止外界调用构造方法创建本类对象

2、创建一个全局唯一对象也做私有化处理

3、通过公共的方法将创建好的对象返回

说到这里可能不明白的小伙伴有点晕,那么我们一起来实现单例模式吧!!

单例模式之饿汉实现

/**
 * @author lin
 * @date 2021/8/24 23:35
 */
public class TestSingle {
    public static void main(String[] args) {
        //4.现在可以通过类名直接调用MySingle方法
        MySingle single1 = MySingle.getSingle();
        MySingle single2 = MySingle.getSingle();
        //5.验证一下这两个对象的地址值是否相等,如果相等,说明单例模式创建成功
        System.out.println(single1);
        System.out.println(single2);
        System.out.println(single1.equals(single2));//true,比较的是地址值说明是同一个对象
    }
}
class MySingle{
    //1.第一步我们首先私有化构造函数
    private  MySingle(){}
    //2.第二步我们就创建一个全局唯一静态对象
    private static MySingle single = new MySingle();
    //3.我们提供一个公共的方法返回该对象
    public static MySingle getSingle(){
        return single;
    }
}

在这里哈给小伙伴总结一下可能会出现的疑惑点

1、为什么在MySing类中创建对象和提供公共方法那里需要用static关键字修饰?

答:在这里我们就有一个问题了MySing成员属性和构造方法都私有化了我们还怎么在main()方法中创建对象,去调用getSinge()方法呀。面对这个问题我们的解决方案就是用static关键字修饰成静态的,因为被static修饰后优先于类先加载,“MySingle single1 = MySingle.getSingle();”这样我们就可以不用创建MySingle对象就能调用getSinge()方法。不知道小伙伴明白没。

单例模式之懒汉实现

/**
 * @author lin
 * @date 2021/8/25 0:02
 */
public class TestSingle01 {
    public static void main(String[] args) {
        Single1 single1 = Single1.getSingle1();
        Single1 single2 =  Single1.getSingle1();
        System.out.println(single1);//Single1@1b6d3586
        System.out.println(single2);//Single1@1b6d3586
        System.out.println(single1.equals(single2));//true,比较的是地址值说明是同一个对象
    }
}
//创建单例程序
class Single1{
    //1.私有化构造方法,为了防止外部调用构造方法创建对象
    private Single1(){}
    //2.创建一个本类类型的引用变量,以便用来保存对象--(延迟加载的思想)
    private static Single1 single1;
    //3.提供对外界可调用的公共方法
    /*注意:这里需要增加一个判断
    如果调用方法时single1的值为null,说明之前没有new过,保存的是默认值
    这时才需要new对象,如果single1的值不为null,直接return single1即可*/
    public static Single1 getSingle1(){
        if (single1 == null){
            single1 = new Single1();//没有对象的时候才创建对象
        }
        return single1;//如果有就直接返回single1
    }
}

总结

1.饿汉式 : 不管你用不用这个类的对象,都会直接先创建一个

2.懒汉式 : 先不给你创建这个类的对象,等你需要的时候再帮你创建--利用了延迟加载的思想

延迟加载的思想:是指不会在第一时间就把对象创建好来占用内存,而是什么时候用到,什么时候再去创建对象

思考问题:共享资源在多线程环境下数据不安全咋解决??

小伙伴们大家思考一下。每天学习一个知识点,今天的你肯定比昨天的你更强。

最近发表
标签列表