Java单例模式--懒汉式和饿汉式(Demo)

简介: 你好我是辰兮,很高兴你能来阅读,本篇文章为大家讲解Java单例模式,相关的更多面试知识已经提前整理好文章可以阅读学习,分享获取新知,希望对Java初学者有帮助。

一、序言

单件模式属于工厂模式的特例,只是它不需要输入参数并且始终返回同一对象的引用。

  • 1、单例类只能有一个实例
  • 2、单例类必须自己创建自己的唯一实例。
  • 3、单例类必须给所有其他对象提供这一实例。

二、饿汉式

饿汉式:在程序启动或单例模式类被加载的时候,单例模式实例就已经被创建。

参考例子如下

  • 我们用HashSet来存储对象,因为HashSet只能存放不同的元素,如果输出的对象唯一,则代表是单例模式。参考class King
  • HashSet类,是存在于java.util包中的类 。同时也被称为集合,该容器中只能存储不重复的对象。
import java.util.HashSet;

public class TheadDemo {

    static HashSet<King> hs = new HashSet<>();
    static Runnable r = new Runnable() {
        @Override
        public void run() {
            //获取单例对象
            King king = King.currentInstance();
            //将获取到的单例对象添加到集合中
            hs.add(king);
        }
    };
    public static void main(String[] args) {
        //需求:多条线程同时去获取单例对象,然后将获取到的单例对象添加到HashSet中
        // 创建多个线程对象,同时访问 单例对象
        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread(r);
            thread.start();           
        }
        System.out.println(hs);
    }
}
//饿汉式
class King {
    private static King instance = new King();
    private King(){}
    public static King currentInstance() {
        return instance;
    }
} 
[King@2cf062b0]

小结:如King类,先创建一个类,直接在内中初始化,再创建一个方法调用这个类返回值是该类的对象。


三、懒汉式

懒汉式:当程序第一次访问单例模式实例时才进行创建。
参考class Queue

ps:懒汉式本身是非线程安全的 --为了实现线程安全加了synchronized

import java.util.HashSet;

public class TheadDemo {

    static HashSet<Queue> hs = new HashSet<>();
    static Runnable r = new Runnable() {
        @Override
        public void run() {
            //获取单例对象
            Queue queue = Queue.currentInstance();
            //将获取到的单Queue对象添加到集合中
            hs.add(queue);
        }
    };
    public static void main(String[] args) {
        //需求:多条线程同时去获取单例对象,然后将获取到的单例对象添加到HashSet中
        // 创建多个线程对象,同时访问 单例对象
        for (int i = 0; i < 100; i++) {
            Thread thread = new Thread(r);
            thread.start();
        }
        System.out.println(hs);
    }

}

//懒汉式
class Queue {
    private static Queue instance;
    private Queue() { }
    //使用同步代码块,同步方法,以及同步锁都可以解决
    public synchronized static Queue currentInstance() {
        if (instance == null) {
            instance = new Queue();
        }
        return instance;
    }
}
[Queue@3cbeafaf]

小结:如Queue类,先创建一个对象没有给他赋值,默认为null,如果调用的话我就自己创建一个对象,再次调用的话就返回原来创建的对象。


四、拓展小结

你一定很好奇为什么叫饿汉式和懒汉式,我们如何记忆呢?

饿汉式:直接new对象,再创建方法调用

public class Singleton {

    private static Singleton instance = new Singleton();

    private Singleton() {
    }

    public static Singleton getInstance() {
        return instance;
    }
}

不管程序是否需要这个对象的实例,总是在类加载的时候就先创建好实例,理解起来就像不管一个人想不想吃东西都把吃的先买好,如同饿怕了一样。


懒汉式:如果需要在创建,如果已经创建则返回原来创建的。

public class Singleton {

    private volatile static Singleton instance = null;

    private Singleton() {
    }

    public static synchronized Singleton getInstance() {
        if (null == instance) {
            instance = new Singleton();
        }
        return instance;
    }
}

如果一个对象使用频率不高,占用内存还特别大,明显就不合适用饿汉式了,这时就需要一种懒加载的思想,当程序需要这个实例的时候才去创建对象,就如同一个人懒的饿到不行了才去吃东西。


The best investment is to invest in yourself

目录
相关文章
|
2月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
45 4
|
2月前
|
设计模式 安全 Java
Java编程中的单例模式:理解与实践
【10月更文挑战第31天】在Java的世界里,单例模式是一种优雅的解决方案,它确保一个类只有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的实现方式、使用场景及其优缺点,同时提供代码示例以加深理解。无论你是Java新手还是有经验的开发者,掌握单例模式都将是你技能库中的宝贵财富。
73 2
|
2月前
|
设计模式 安全 Java
Java编程中的单例模式深入解析
【10月更文挑战第31天】在编程世界中,设计模式就像是建筑中的蓝图,它们定义了解决常见问题的最佳实践。本文将通过浅显易懂的语言带你深入了解Java中广泛应用的单例模式,并展示如何实现它。
|
2月前
|
设计模式 SQL 安全
Java编程中的单例模式深入解析
【10月更文挑战第24天】在软件工程中,单例模式是设计模式的一种,它确保一个类只有一个实例,并提供一个全局访问点。本文将探讨如何在Java中使用单例模式,并分析其优缺点以及适用场景。
19 0
|
安全 Java
Java常用的单例模式
Java常用的单例模式
132 0
|
安全 Java
Java常用的单例模式
版权声明:欢迎转载,请注明沉默王二原创。 https://blog.csdn.net/qing_gee/article/details/46608497 Java的单例single经常用到,但是使用枚举enum最佳。
948 0
|
4天前
|
监控 Java
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
42 17
|
15天前
|
Java
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
|
17天前
|
安全 Java Kotlin
Java多线程——synchronized、volatile 保障可见性
Java多线程中,`synchronized` 和 `volatile` 关键字用于保障可见性。`synchronized` 保证原子性、可见性和有序性,通过锁机制确保线程安全;`volatile` 仅保证可见性和有序性,不保证原子性。代码示例展示了如何使用 `synchronized` 和 `volatile` 解决主线程无法感知子线程修改共享变量的问题。总结:`volatile` 确保不同线程对共享变量操作的可见性,使一个线程修改后,其他线程能立即看到最新值。
|
17天前
|
消息中间件 缓存 安全
Java多线程是什么
Java多线程简介:本文介绍了Java中常见的线程池类型,包括`newCachedThreadPool`(适用于短期异步任务)、`newFixedThreadPool`(适用于固定数量的长期任务)、`newScheduledThreadPool`(支持定时和周期性任务)以及`newSingleThreadExecutor`(保证任务顺序执行)。同时,文章还讲解了Java中的锁机制,如`synchronized`关键字、CAS操作及其实现方式,并详细描述了可重入锁`ReentrantLock`和读写锁`ReadWriteLock`的工作原理与应用场景。
下一篇
开通oss服务