反射与单例设计模式 | 带你学《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");
    }
}
AI 代码解读

多线程状态执行:

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");
    }
}
AI 代码解读

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

这个时候的确是进行了同步处理,但这个同步处理的代价有些大,因为效率会低。因为整体代码中实际上只有一块部分需要进行同步处理,也就是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");
    }
}
AI 代码解读

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

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

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

目录
打赏
0
0
0
0
280
分享
相关文章
反射-----浅解析(Java)
在java中,我们可以通过反射机制,知道任何一个类的成员变量(成员属性)和成员方法,也可以堆任何一个对象,调用这个对象的任何属性和方法,更进一步我们还可以修改部分信息和。
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
Java基础——反射
本文介绍了Java反射机制的基本概念和使用方法,包括`Class`类的使用、动态加载类、获取方法和成员变量信息、方法反射操作、以及通过反射了解集合泛型的本质。同时,文章还探讨了动态代理的概念及其应用,通过实例展示了如何利用动态代理实现面向切面编程(AOP),例如为方法执行添加性能监控。
JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式
本文深入探讨了JavaScript设计模式及其在实战中的应用,涵盖单例、工厂、观察者、装饰器和策略模式,结合电商网站案例,展示了设计模式如何提升代码的可维护性、扩展性和可读性,强调了其在前端开发中的重要性。
49 2
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
49 4
|
2月前
|
Java的反射
Java的反射。
43 2
|
3月前
|
[Java]反射
本文详细介绍了Java反射机制的基本概念、使用方法及其注意事项。首先解释了反射的定义和类加载过程,接着通过具体示例展示了如何使用反射获取和操作类的构造方法、方法和变量。文章还讨论了反射在类加载、内部类、父类成员访问等方面的特殊行为,并提供了通过反射跳过泛型检查的示例。最后,简要介绍了字面量和符号引用的概念。全文旨在帮助读者深入理解反射机制及其应用场景。
53 0
[Java]反射
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
|
17天前
|
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
74 17
|
27天前
|
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者

热门文章

最新文章

  • 1
    设计模式转型:从传统同步到Python协程异步编程的实践与思考
    64
  • 2
    C++一分钟之-设计模式:工厂模式与抽象工厂
    55
  • 3
    《手把手教你》系列基础篇(九十四)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-下篇(详解教程)
    63
  • 4
    C++一分钟之-C++中的设计模式:单例模式
    79
  • 5
    《手把手教你》系列基础篇(九十三)-java+ selenium自动化测试-框架设计基础-POM设计模式实现-上篇(详解教程)
    49
  • 6
    《手把手教你》系列基础篇(九十二)-java+ selenium自动化测试-框架设计基础-POM设计模式简介(详解教程)
    81
  • 7
    Java面试题:结合设计模式与并发工具包实现高效缓存;多线程与内存管理优化实践;并发框架与设计模式在复杂系统中的应用
    70
  • 8
    Java面试题:设计模式在并发编程中的创新应用,Java内存管理与多线程工具类的综合应用,Java并发工具包与并发框架的创新应用
    54
  • 9
    Java面试题:如何使用设计模式优化多线程环境下的资源管理?Java内存模型与并发工具类的协同工作,描述ForkJoinPool的工作机制,并解释其在并行计算中的优势。如何根据任务特性调整线程池参数
    63
  • 10
    Java面试题:请列举三种常用的设计模式,并分别给出在Java中的应用场景?请分析Java内存管理中的主要问题,并提出相应的优化策略?请简述Java多线程编程中的常见问题,并给出解决方案
    137
  • AI助理

    你好,我是AI助理

    可以解答问题、推荐解决方案等