多线程(初阶六:单例模式)

一、单例模式的简单介绍

二、饿汉模式

三、懒汉模式

四、饿汉模式和懒汉模式的线程安全问题分析

一、单例模式的简单介绍

单例模式是一种设计模式,其中设计模式是软性的规定,与它关联的框架是硬性的规定,这些都是大佬已经设计好了的,即使是代码写的不是很好的菜鸡,按照这种模式也能写出还行的代码。类似象棋中的棋谱,即使你是新手,但按着棋谱走,你的棋力也不会太差。

单例 = 单个实例(对象)某个类,在一个线程中,只应该创建一个对象(原则上不应该有多个),这时就使用单例模式,就可以对我们的代码进行一个更严格的校验和检查

那么,怎么保证这一个对象唯一呢?

其一方法,可以通过"君子约定",写一个文档,规定这个类只能有唯一的实例,新手程序猿接手这个代码时,就会发一份这个文档,进行约定,熟悉其中的规定、条约。

其二方法:可以让机器帮我们检查,人肯定是没有机器靠谱的,我们期望让机器帮我们对代码中指定的类,创建类的实例个数进行检查、校验,当创建的实例个数超过我们期望个数,就编译报错,这一点还是能实现的,其中单例模式就是已经设计好的套路,可以实现这种预期效果。


二、饿汉模式

**饿汉模式是指创建实例是时期非常早,在类加载的时候,程序一启动,就已经创建好实例了,使用 "饿汉"这个词,就是形容创建实例非常迫切,非常早。**下面实现一个单例模式

代码:

java 复制代码
class Singleton {
    private static Singleton instance = new Singleton();
    public static Singleton getInstance() {
        return instance;
    }
    private Singleton(){ }
}
public class TestDemo4 {
    public static void main(String[] args) {
        
    }
}

当我们想在主线程中创建一个Singleton的实例时,会报错,如图:

singleton类的代码解析:

singleton内部,第一行代码就是这个,如图

这说明,singleton内部一开始就创建好了实例,创建实例非常迫切,使用static修饰说明instance是类属性。

接下来是获取这个类的实例方法,如图

因为我们不希望能创建出多个实例,所以就把singleton的构造方法用private来修饰,如图:

这样,如果我们想new一个Singleton对象,也new不了,但也有非正规手段,去获取singleton里面的属性或方法:反射。

最后,不管我们用getInstance获取多少次实例,获取的对象都是同一个对象,验证如下:

代码:

java 复制代码
class Singleton {
    private static Singleton instance = new Singleton();
    public static Singleton getInstance() {
        return instance;
    }
    private Singleton(){ }
}
public class TestDemo4 {
    public static void main(String[] args) {
        Singleton s1 = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s1 == s2);
    }
}

执行结果:

三、懒汉模式

和饿汉模式不一样的是,创建实例的时机比较晚,没饿汉创建实例那么迫切,只有第一次使用这个类时,才会创建实例。

代码如下:

java 复制代码
class SingletonLazy {
    private static SingletonLazy instance = null;
    public static SingletonLazy getInstance() {
        if(instance == null) {
            instance = new SingletonLazy();
        }
        return instance;
    }
    private SingletonLazy() { }
}
public class TestDemo5 {
    public static void main(String[] args) {

    }
}

代码解析:

一开始,没有创建实例,只是给singletonLazy赋值为null,并没有new一个对象,也就是没有创建实例;首次调用getInstance,instance是null的,所以会new一个对象,创建实例。如果不是第一次调用getInstance,就直接返回instance,这也保证了这个类的实例是唯一的,只有一个实例;

和饿汉模式的区别就是没那么迫切创建实例,等需要调用这个类的时候才创建一个实例,而饿汉模式是有了这个类就创建出实例。

懒汉模式的优点:有的程序,要在一定条件下,才需要进行相关的操作,有时候不满足这个条件,也就不需要完成这个操作了,这样,就把这个操作省下来了,而懒汉模式,就是这一思想,当需要这个实例时,才创建实例。像肯德基的疯狂星期四,只有在星期四的时候才会加载出相关信息,其他时间就不会加载。


四、饿汉模式和懒汉模式的线程安全问题分析

相关推荐
VBA63371 分钟前
VBA数据库解决方案第十五讲:Recordset集合中单个数据的精确处理
开发语言
wrx繁星点点5 分钟前
事务的四大特性(ACID)
java·开发语言·数据库
不写八个11 分钟前
Python办公自动化教程(005):Word添加段落
开发语言·python·word
IT学长编程12 分钟前
计算机毕业设计 Java酷听音乐系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·课程设计·毕业论文·音乐系统·计算机毕业设计选题
HEX9CF16 分钟前
【CTF Web】Pikachu xss之href输出 Writeup(GET请求+反射型XSS+javascript:伪协议绕过)
开发语言·前端·javascript·安全·网络安全·ecmascript·xss
IT学长编程29 分钟前
计算机毕业设计 基于协同过滤算法的个性化音乐推荐系统的设计与实现 Java实战项目 附源码+文档+视频讲解
java·spring boot·毕业设计·毕业论文·协同过滤算法·计算机毕业设计选题·个性化音乐推荐系统
小小娥子34 分钟前
Redis的基础认识与在ubuntu上的安装教程
java·数据库·redis·缓存
赵荏苒41 分钟前
Python小白之Pandas1
开发语言·python
几何心凉42 分钟前
已解决:org.springframework.web.HttpMediaTypeNotAcceptableException
java
丶Darling.42 分钟前
代码随想录 | Day26 | 二叉树:二叉搜索树中的插入操作&&删除二叉搜索树中的节点&&修剪二叉搜索树
开发语言·数据结构·c++·笔记·学习·算法