反射与单例设计模式 | 带你学《Java语言高级特性》之八十四

简介: 通过案例引出懒汉式的单例设计模式所出现的问题,并使用使用synchronized关键字来处理解决。

上一篇:反射与工厂设计模式 | 带你学《Java语言高级特性》之八十三
【本节目标】
通过案例引出懒汉式的单例设计模式所出现的问题,并使用使用synchronized关键字来处理解决。

反射与单例设计模式

单例设计模式的核心本质在于:类内部的构造方法私有化,在类的内部产生实例化对象后通过static方法获取实例化对象,进行类中的结构调用,单例设计模式一共有两类:懒汉式、饿汉式,本节主要来讨论懒汉式的单例设计模式。

范例:观察懒汉式单例设计模式的问题
单线程状态执行:

public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        Singleton sinA = Singleton.getInstance();
        sinA.print();
    }
}
class Singleton {
    private static Singleton instance = null;
    private Singleton() {}
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
    public void print() {
        System.out.println("www.mldn.cn");
    }
}

多线程状态执行:

public class JavaAPIDemo {
    public static void main(String[] args) throws Exception {
        for (int x = 0; x < 3; x++) {
            new Thread(()->{
                Singleton.getInstance().print();
            },"单例消费端-"+ x).start();
        }
        /**
         * 【单例消费端-0】****** 实例化Singleton类对象 *******
         * 【单例消费端-1】****** 实例化Singleton类对象 *******
         * www.mldn.cn
         * 【单例消费端-2】****** 实例化Singleton类对象 *******
         * www.mldn.cn
         * www.mldn.cn
         */
    }
}
class Singleton {
    private static Singleton instance = null;
    private Singleton() {
        System.out.println("【" + Thread.currentThread().getName() +"】****** 实例化Singleton类对象 *******",Thread.currentThread().getName());
    }
    public static Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
    public void print() {
        System.out.println("www.mldn.cn");
    }
}

单例设计模式的最大特点是在整体的运行程序中只允许产生一个实例化对象,但当有了若干个线程之后,实际上当前的程序就会产生多个实例化对象了,此时就不是单例设计模式了。此时问题造成的关键在于代码本身出现了不同步的情况,而要想解决的关键就在于同步处理,也就是需要使用synchronized关键字。

image.png
单例设计模式问题

范例:修改getInstance()进行同步处理

class Singleton {
    private static Singleton instance = null;
    private Singleton() {
        System.out.println("【" + Thread.currentThread().getName() +"】****** 实例化Singleton类对象 *******",Thread.currentThread().getName());
    }
    public static synchronized Singleton getInstance() {
        if (instance == null) {
            instance = new Singleton();
        }
        return instance;
    }
    public void print() {
        System.out.println("www.mldn.cn");
    }
}

这个时候的确是进行了同步处理,但这个同步处理的代价有些大,因为效率会低。因为整体代码中实际上只有一块部分需要进行同步处理,也就是instance对象的实例化处理部分。我们可以知道,之前的同步操作是有些失误的。

范例:更加合理地进行同步处理

class Singleton {
    private static volatile Singleton instance = null;
    private Singleton() {
        System.out.printf("【" + Thread.currentThread().getName() +"】****** 实例化Singleton类对象 *******",Thread.currentThread().getName());
    }
    public static Singleton getInstance() {
        if (instance == null) {
            synchronized (Singleton.class) {
                if (instance == null) {
                    instance = new Singleton();
                }
            }
        }
        return instance;
    }
    public void print() {
        System.out.println("www.mldn.cn");
    }
}

面试题:请编写单例设计模式
直接编写一个饿汉式的单例设计模式,并且实现构造方法私有化;
在Java中哪里使用到了单例设计模式?
Runtime类、Pattern类、Spring框架;
懒汉式单例模式的问题
即上面描述所出现的问题。
单例设计模式的最大特点是在整体的运行程序中只允许产生一个实例化对象,但当有了若干个线程之后,实际上当前的程序就会产生多个实例化对象了,此时就不是单例设计模式了。此时问题造成的关键在于代码本身出现了不同步的情况,而要想解决的关键就在于同步处理,也就是需要使用synchronized关键字。

想学习更多的Java的课程吗?从小白到大神,从入门到精通,更多精彩不容错过!免费为您提供更多的学习资源。
本内容视频来源于阿里云大学

下一篇:反射获取类结构信息 | 带你学《Java语言高级特性》之八十五
更多Java面向对象编程文章查看此处

相关文章
|
21天前
|
Java Maven
使用java语言制作一个窗体(弹窗),用来收集用户输入的内容
该博客文章介绍了如何使用Java Swing中的JFrame创建一个窗体来收集用户输入的内容,并提供了详细的实现步骤和完整代码示例。
使用java语言制作一个窗体(弹窗),用来收集用户输入的内容
|
19天前
|
设计模式 算法 Java
Java中的设计模式:提升代码质量的秘诀
【8月更文挑战第23天】在Java开发中,设计模式是提高代码可读性、可维护性和扩展性的强有力工具。本文通过浅显易懂的语言和实际案例,探讨几种常见的设计模式及其在Java中的应用,旨在帮助开发者更好地理解并运用这些模式来优化自己的代码结构。
37 2
|
12天前
|
设计模式 缓存 算法
揭秘策略模式:如何用Java设计模式轻松切换算法?
【8月更文挑战第30天】设计模式是解决软件开发中特定问题的可重用方案。其中,策略模式是一种常用的行为型模式,允许在运行时选择算法行为。它通过定义一系列可互换的算法来封装具体的实现,使算法的变化与客户端分离。例如,在电商系统中,可以通过定义 `DiscountStrategy` 接口和多种折扣策略类(如 `FidelityDiscount`、`BulkDiscount` 和 `NoDiscount`),在运行时动态切换不同的折扣逻辑。这样,`ShoppingCart` 类无需关心具体折扣计算细节,只需设置不同的策略即可实现灵活的价格计算,符合开闭原则并提高代码的可维护性和扩展性。
28 2
|
12天前
|
设计模式 Java
Java 设计模式之谜:工厂模式与抽象工厂模式究竟隐藏着怎样的神奇力量?
【8月更文挑战第30天】在Java编程中,设计模式为常见问题提供了高效解决方案。工厂模式与抽象工厂模式是常用的对象创建型设计模式,能显著提升代码的灵活性、可维护性和可扩展性。工厂模式通过定义创建对象的接口让子类决定实例化哪个类;而抽象工厂模式则进一步提供了一个创建一系列相关或相互依赖对象的接口,无需指定具体类。这种方式使得系统更易于扩展和维护。
23 1
|
12天前
|
设计模式 Java
重构你的代码:探索Java中的混合、装饰器与组合设计模式
【8月更文挑战第30天】在软件开发中,设计模式为特定问题提供了结构化的解决方案,使代码更易理解、维护及扩展。本文将介绍三种常用的 Java 设计模式:混合模式、装饰器模式与组合模式,并附有示例代码展示实际应用。混合模式允许通过继承多个接口或抽象类实现多重继承;装饰器模式可在不改变对象结构的情况下动态添加新功能;组合模式则通过树形结构表示部分-整体层次,确保客户端处理单个对象与组合对象时具有一致性。
10 1
|
22天前
|
设计模式 算法 安全
Java编程中的设计模式:提升代码的可维护性和扩展性
【8月更文挑战第19天】在软件开发的世界里,设计模式是解决常见问题的一种优雅方式。本文将深入探讨Java编程语言中常用的几种设计模式,并解释如何通过这些模式来提高代码的可维护性和扩展性。文章不涉及具体的代码实现,而是侧重于理论和实践相结合的方式,为读者提供一种思考和改善现有项目的新视角。
|
23天前
|
设计模式 Java
常用设计模式介绍~~~ Java实现 【概念+案例+代码】
文章提供了一份常用设计模式的全面介绍,包括创建型模式、结构型模式和行为型模式。每种设计模式都有详细的概念讲解、案例说明、代码实例以及运行截图。作者通过这些模式的介绍,旨在帮助读者更好地理解源码、编写更优雅的代码,并进行系统重构。同时,文章还提供了GitHub上的源码地址,方便读者直接访问和学习。
常用设计模式介绍~~~ Java实现 【概念+案例+代码】
|
23天前
|
设计模式 算法 Java
【十六】设计模式~~~行为型模式~~~策略模式(Java)
文章详细介绍了策略模式(Strategy Pattern),这是一种对象行为型模式,用于定义一系列算法,将每个算法封装起来,并使它们可以相互替换。策略模式让算法独立于使用它的客户而变化,提高了系统的灵活性和可扩展性。通过电影院售票系统中不同类型用户的打折策略案例,展示了策略模式的动机、定义、结构、优点、缺点以及适用场景,并提供了Java代码实现和测试结果。
【十六】设计模式~~~行为型模式~~~策略模式(Java)
|
23天前
|
设计模式 网络协议 Java
【十五】设计模式~~~行为型模式~~~状态模式(Java)
文章详细介绍了状态模式(State Pattern),这是一种对象行为型模式,用于处理对象在其内部状态改变时的行为变化。文中通过案例分析,如银行账户状态管理和屏幕放大镜工具,展示了状态模式的应用场景和设计方法。文章阐述了状态模式的动机、定义、结构、优点、缺点以及适用情况,并提供了Java代码实现和测试结果。状态模式通过将对象的状态和行为封装在独立的状态类中,提高了系统的可扩展性和可维护性。
【十五】设计模式~~~行为型模式~~~状态模式(Java)
|
17天前
|
设计模式 缓存 算法
探索 Java 设计模式及其重要性
【8月更文挑战第24天】
41 0
下一篇
DDNS