日志

彻底弄懂 单例设计模式

 来源    2020-09-16    0  

一、设计模式简介

设计模式是在大量的实践中总结和理论化之后优选的代码结构、编程风格、以及解决问题的思考方式。设计模免去我们自己再思考和摸索。就像是经典的棋谱,不同的棋局,我们用不同的棋谱。”套路”

二、单例设计模式

2.1 单列设计模式简介

所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法。

2.2 单例设计模式优点

由于单例模式只生成一个实例,减少了系统性能开销,当一个对象的产生需要比较多的资源时,如读取配置、产生其他依赖对象时,则可以通过在应用启动时直接产生一个单例对象,然后永久驻留内存的方式来解决。

2.3 单例设计模式思路

  1. 如果我们要让类在一个虚拟机中只能产生一个对象,我们首先必须将类的构造器的访问权限设置为private【private权限修饰符,可以修饰成员变量、成员方法、内部类。作用:只能在本类中使用privite修饰的成员变量、成员方法】,这样,就不能用new操作符在类的外部产生类的对象了,但在类内部仍可以产生该类的对象。

  2. 因为在类的外部开始还无法得到类的对象,只能调用该类的某个静态方法以返回类内部创建的对象,静态方法只能访问类中的静态成员变量,所以,指向类内部产生的该类对象的变量也必须定义成静态的。

2.4 单例(Singleton)设计模式-饿汉式

直接上代码:

/**单例(Singleton)设计模式-饿汉式
 * private权限修饰符,可以修饰成员变量、成员方法、内部类。作用:只能在本类中使用private修饰的成员变量、成员方法】
 */
public class Student {
    
    // 第一步:私有化构造器。【让外部无法通过new来创建对象】
    private Student() {
    }

    
    // 第二步:创建一个对象
    /*  1. 为什么怎么做?
           不怎么做的话,我们就没有对象呀!构造器已经被我们设置为私有的了,外部不能造对象了,那我们就只能在内部提供一个对象。
        2. 为什么设置为私有的?
            想一想,如果不设置为私有的。当有一个类继承这个类的时候,该子类就可以访问这个属性了,从而得到了父类对象。
            这与我们初衷相违背。
        3.为什么设置为静态的?
            看第三步中的回答,从第三步反推过来的。需要把这个属性设置为私有的。
    * */
    private static Student student = new Student();

    
    // 第三步:对外提供一个公共静态方法。【以便获得第二步中创建的对象】
    /*1. 为什么是公共的?
    *    肯定是公共的,不然如私有方法,外部怎么能够访问得了,从而怎么得到这个唯一的对象
    * 2. 为什么是静态方法?
    *     第一:如果不是静态方法,我们需要通过new对象来访问该方法,和我们初衷相违背。
    *     第二:静态方法,我们可以通过类名.方法名的方式进行访问。
    *     第三:静态方法里面只能访问静态属性、静态方法,从而反推出第二步骤中的属性需要加static关键字
    * */

    public static Student getStudent() {
        return student;
    }
}

测试:

public class TestStudent {
    public static void main(String[] args) {
       // 1. 我们先来new一下,发现编译失败。【说明:外部通过构造器无法创建对象】
       // Student student = new Student();

        // 2. 比较创出的对像否是同一个对象,结果为true。【说明:证明是同一个对象】
        Student student1 = Student.getStudent();
        Student student2 = Student.getStudent();
        System.out.println(student1==student2);
    }
}

2.5 单例(Singleton)设计模式-懒汉式

错误写法:第三步有问题

/**
 * 单例(Singleton)设计模式-懒汉式
 */
public class Teacher {
    // 第一步:私有化构造器
    private Teacher() {

    }
    // 第二步:声明当前类对象,没有初始化
    private static Teacher teacher=null;

    // 第三步:提供公共静态方法,返回当前类的对象
    public static Teacher getTeacher() {
        Teacher teacher = new Teacher();
        return teacher;
    }
}

测试:这显然是两个对象

错误原因:调用一次方法,便会new一次,创建不同的对象。

正确写法:

/**
 * 单例(Singleton)设计模式-懒汉式
 */
public class Teacher {
    // 第一步:私有化构造器
    private Teacher() {

    }
    // 第二步:声明当前类对象,没有初始化
    private static Teacher teacher=null;

    // 第三步:提供公共静态方法,返回当前类的对象
    public static Teacher getTeacher() {
        if (teacher == null) {    // 先判断一下,如果该对象没有创建就new,return出去。如果已经有了就不创建了。
            Teacher teacher = new Teacher();
        }
        return teacher;
    }
}

2.6 饿汉式VS懒汉式

  1. 饿汉式

    ​ 坏处:对象加载时间过长【占用内存】

    ​ 好处:饿汉式是线程安全的

  2. 懒汉式

    ​ 好处:延迟对象的创建

    ​ 坏处:目前的写法,存在线程不安全。

    【线程不安全解释:假设有两个线程进入了getTeacher方法,线程一判断teacher会null时,此时CPU资源给到了线程二(线程一没有执行Teacher teacher = new Teacher()

相关文章
设计模式 – 依赖注入和单例设计模式
问答我们如何确定何时使用依赖注入或单例模式. 我读了很多网站,他们说"使用依赖注入单形模式".但我不知道我是否完全同意他们.对于我的小型或中型项目,我绝对看到使用单例模式直截了当. 例 ...
3
java – 关于单例设计模式
问答我正在探索单身设计模式,我开发了一个类-- public class SingletonObject { private static SingletonObject ref; private Sin ...
1
java – 单例设计模式和防止克隆
问答关于Singleton设计模式的很多文章都提到,该类应该覆盖'clone()'方法,并在其中抛出'CloneNotSupported'异常.这真的有必要吗? 默认情况下,clone()方法是受保护的, ...
1
java – 正确使用单例设计模式
问答我正在运行一个服务器,有时必须搜索客户端查询的内容.我想将客户端查询写入磁盘以获取记录,但我不想放慢搜索速度. (搜索已经成为瓶颈--) 因此,当客户端执行搜索时,我让客户端的线程向单个线程发送消息, ...
1
c# – 单例设计模式与静态类
问答当Singleton设计模式优于静态类和&时,情况有哪些?什么时候静态类优于Singleton设计模式?::这不是一个或两个场景. 单例是具有静态getter和私有构造函数的实例.它们不是静态 ...
1
单例设计模式(详解)
日志单例设计模式 模式:模式就是解决一类问题的固定步骤 单例设计模式:保证一个类在内存中只有一个对象 举例:多个浏览器向服务器发送请求,只创建一个servlet对象处理相应的请求,而不是每接收一个请求,就 ...
1
单例设计模式八种写法
日志所谓类的单例设计模式,就是采取一定的方法保证在整个的软件系统中,对某个类 只能存在一个对象实例,并且该类只提供一个取得其对象实例的方法(静态方法). 比如Hibernate的SessionFactor ...
由单例设计模式之静态内部类实现方式引出的对于内部类加载时机及其设计初衷的几点疑惑及解析
日志前言快速到底 对于单例设计模式之静态内部类的实现方式存在以下疑点:①为什么内部类中如果有静态的变量,那么这个内部类就必须是静态内部类(换一句话问:普通的内部类为什么不能有静态的成员变量)?②外部类加载 ...
1
单例设计模式
日志前言快速到底 本文的关注点将重点放在单例模式的写法以及每种写法的线程安全性上.所谓 "线程安全" 的意思就是保证在创建单例对象的时候不存在竞争,只会创建出一个单例对象. 单例模式 ...
1
单例设计模式Singleton之懒加载模式(懒汉模式)原
日志单例设计模式Singleton之懒加载模式(懒汉模式) SingletonLazy.java类 package kingtool; import kingtool.http.IPTool; publi ...
1
python基础--反射、元类、单例设计模式
日志反射:reflect,反射指的是一个对象应该具备可以检测.修改.增加自身属性的能力,反射就是通过字符串操作属性 hasattr(对象,带查询的属性名称)  判断某个对象中是否存在某个属性 getatt ...
1
[javaSE] 单例设计模式
日志四人帮设计了23中设计模式 单例设计模式:解决一个类在内存中只存在一个对象 构造函数私有化 在类中创建一个本类对象 提供一个方法可以获取该对象 class Single{ private static ...
java设计模式——单例设计模式
日志/*设计模式:对问题行之有效的解决方式.其实它是一种思想.1,单例设计模式.    解决的问题:就是可以保证一个类在内存中的对象唯一性.必须对于多个程序使用同一个配置信息对象时,就需要保证该对象的唯一 ...
2
Python 单例设计模式
日志class Foo: def __init__(self, name, age): self.name = name self.age = age def show(self): print(self ...
1
Java 单例设计模式之 饿汉式和懒汉式
日志public class InstanceSampleTest { public static void main(String[] args) { /** 单例设计模式的 饿汉式和懒汉式 * 单例模 ...
死锁、Lock锁、等待唤醒机制、线程组、线程池、定时器、单例设计模式_DAY24
日志1:线程(理解)     (1)死锁        概念:            同步中,多个线程使用多把锁之间存在等待的现象.        原因分析:          a.线程1将锁1锁住,线程 ...
1
设计模式(一)__单例设计模式
日志先来介绍一下什么是设计模式,设计模式起先是从建筑行业借鉴来的,然后慢慢发展到了今天这个样子. 设计模式是解决问题最行之有效的思想,是一套被反复使用.多数人知晓的.经过分类编目的.代码设计经验的总结.使 ...
1
(三十二)单例设计模式
日志/** 设计模式:解决某一类问题最有效的方式(23种设计模式) 单例设计模式:保证一个类只有一个对象 1.构造函数私有化,禁止外部使用实例化new 2.再类内部创建一个自身类型的对象 3.使用一个pu ...
(二十九)设计模式之单例设计模式
日志 单例模式的思路是:一个类能返回一个对象的引用(并且永远是同一个)和一个获得该实例的方法(静态方法,通常使用 getInstance 名称).那么当我们调用这个方法时,如果类持有的引用不为空就返回该引 ...
1
Java 单例设计模式
日志单例设计模式 所谓的单例设计模式,就是指一个类只能实例化一个对象 范例:一个简单的程序 class Singleton{ public void print() { System.out.printl ...
1