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

目录
相关文章
|
1月前
|
设计模式 安全 Java
Java 编程中的设计模式:单例模式的深度解析
【9月更文挑战第22天】在Java的世界里,单例模式就像是一位老练的舞者,轻盈地穿梭在对象创建的舞台上。它确保了一个类仅有一个实例,并提供全局访问点。这不仅仅是代码优雅的体现,更是资源管理的高手。我们将一起探索单例模式的奥秘,从基础实现到高级应用,再到它与现代Java版本的舞蹈,让我们揭开单例模式的面纱,一探究竟。
31 11
|
6天前
|
设计模式 SQL 安全
【编程进阶知识】Java单例模式深度解析:饿汉式与懒汉式实现技巧
本文深入解析了Java单例模式中的饿汉式和懒汉式实现方法,包括它们的特点、实现代码和适用场景。通过静态常量、枚举类、静态代码块等方式实现饿汉式,通过非线程安全、同步方法、同步代码块、双重检查锁定和静态内部类等方式实现懒汉式。文章还对比了各种实现方式的优缺点,帮助读者在实际项目中做出更好的设计决策。
22 0
|
1月前
|
设计模式 Java 安全
Java设计模式-单例模式(2)
Java设计模式-单例模式(2)
|
2月前
|
设计模式 安全 Java
Java编程中的单例模式深度解析
【8月更文挑战第31天】 单例模式,作为设计模式中的经典之一,在Java编程实践中扮演着重要的角色。本文将通过简洁易懂的语言,逐步引导读者理解单例模式的本质、实现方法及其在实际应用中的重要性。从基础概念出发,到代码示例,再到高级应用,我们将一起探索这一模式如何优雅地解决资源共享和性能优化的问题。
|
4天前
|
安全 Java UED
Java中的多线程编程:从基础到实践
本文深入探讨了Java中的多线程编程,包括线程的创建、生命周期管理以及同步机制。通过实例展示了如何使用Thread类和Runnable接口来创建线程,讨论了线程安全问题及解决策略,如使用synchronized关键字和ReentrantLock类。文章还涵盖了线程间通信的方式,包括wait()、notify()和notifyAll()方法,以及如何避免死锁。此外,还介绍了高级并发工具如CountDownLatch和CyclicBarrier的使用方法。通过综合运用这些技术,可以有效提高多线程程序的性能和可靠性。
|
4天前
|
缓存 Java UED
Java中的多线程编程:从基础到实践
【10月更文挑战第13天】 Java作为一门跨平台的编程语言,其强大的多线程能力一直是其核心优势之一。本文将从最基础的概念讲起,逐步深入探讨Java多线程的实现方式及其应用场景,通过实例讲解帮助读者更好地理解和应用这一技术。
22 3
|
8天前
|
Java 调度 UED
深入理解Java中的多线程与并发机制
本文将详细探讨Java中多线程的概念、实现方式及并发机制,包括线程的生命周期、同步与锁机制以及高级并发工具。通过实例代码演示,帮助读者理解如何在Java中有效地处理多线程和并发问题,提高程序的性能和响应能力。
|
6天前
|
缓存 安全 Java
使用 Java 内存模型解决多线程中的数据竞争问题
【10月更文挑战第11天】在 Java 多线程编程中,数据竞争是一个常见问题。通过使用 `synchronized` 关键字、`volatile` 关键字、原子类、显式锁、避免共享可变数据、合理设计数据结构、遵循线程安全原则和使用线程池等方法,可以有效解决数据竞争问题,确保程序的正确性和稳定性。
13 2
|
7天前
|
存储 安全 Java
Java-如何保证线程安全?
【10月更文挑战第10天】
|
8天前
|
Java