【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列

这篇具有很好参考价值的文章主要介绍了【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1、单例模式

1.1、饿汉模式

2.1、懒汉模式 

2、阻塞队列

2.1、BlockingQueue 阻塞队列数据结构



【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列,java,单例模式,开发语言,多线程,笔记

1、单例模式

对框架和设计模式的简单理解就是,这两者都是“大佬”设计出来的,让即使是一个代码写的不太好的“菜鸡程序员”也能写出还可以的代码。设计模式也可以认为是对编程语言语法的补充此处提到的“单例模式”就是一种设计模式。

框架(硬性的规定)

设计模式(软性的规定)遵循设计模式,代码的下限就被兜住了,类似下棋时的“棋谱”。

单例,顾名思义,单个实例(对象)。某个类,在一个进程中,只应该创建出一个实例(原则上不应该有多个)。使用单例模式,就可以对代码进行一个更严格的校验和检查。

1.1、饿汉模式

饿汉模式的“创建时机”非常早,实例在类加载的时候就被创建了,相当于程序一启动实例就创建了。因此使用“饿汉”来形容实例创建的迫切,非常早。【并且由于只涉及到读操作,天然的线程安全。】

package thread;

// 期望这个类只能有唯一的实例 (一个进程中)
class Singleton {
    private static Singleton instance = new Singleton();//static修饰的类对象,只存在一个

    public static Singleton getInstance() {   //只提供一个方法获取静态(类属性)实例
        return instance;   //只涉及到读操作,天然的线程安全
    }

    private Singleton() {}   //使用private修饰构造方法,使得无法使用new创建实例
}

public class ThreadDemo26 {
    public static void main(String[] args) {
        // Singleton s = new Singleton();   //无法new
        Singleton s = Singleton.getInstance();
        Singleton s2 = Singleton.getInstance();
        System.out.println(s == s2);   //true
    }
}

在代码中,使用static修饰了一个类对象,然后提供一个方法来获得这个对象,再使用 private 修饰构造方法,使得无法通过 new 创建实例。,由于该实例使用了 static 修饰,在类加载时就已经存在,所以就是懒汉模式。

2.1、懒汉模式 

懒汉模式的实例创建时机相比于饿汉模式要更晚,直到第一次使用的时候,才会创建实例。相比“饿汉模式”,“懒汉模式”效率更高。

 举个例子:

有一个编辑器想要打开一个10GB的文件,如果按照“饿汉”的方式,编辑器就会先把10GB的数据都加载到内存中,然后再进行统一展示;

如果按照“懒汉”的方式,编辑器就会只读取一小部分数据(比如只读10KB),把10KB先展示出来,随着用户进行翻页等操作,再继续读取后续的数据。

package thread;

// 懒汉的方式实现单例模式.
class SingletonLazy {
    // 这个引用指向唯一实例. 这个引用先初始化为 null, 而不是立即创建实例
    private volatile static SingletonLazy instance = null;   //volatile禁止重排序
    private static Object locker = new Object();

    public static SingletonLazy getInstance() {  //将创建实例的操作放到了getInstance里
        if (instance == null) {   //【注意理解此处的两个if】
            synchronized (locker) {    //考虑线程安全,需要加锁
                if (instance == null) {   //【注意理解此处的两个if】
                    instance = new SingletonLazy();
                }
            }
        }
        return instance;
    }

    private SingletonLazy() { }
}

public class ThreadDemo27 {
    public static void main(String[] args) {
        SingletonLazy s1 = SingletonLazy.getInstance();
        SingletonLazy s2 = SingletonLazy.getInstance();
        System.out.println(s1 == s2);   //true
    }
}

如果 Instance 为 null, 就说明是首次调用, 首次调用就需要考虑线程安全问题, 就要加锁。

如果非 null, 就说明是后续的调用, 就不必加锁了。


讲解第10行和第12行的 if 语句:(双重校验锁)

这样相同且连续的 if 代码从来没写过,这是因为之前写的代码都是在单线程却无阻塞的情况,这种情况下连续两个相同的 if 是无意义的;

但是涉及到阻塞以及多线程的情况,这样的代码就非常的有意义了。看上去是两个一样的条件,实际上这两个条件的结果可能是相反的。

第一个 if 判定的是是否要加锁,如果不是首次调用时就跳过加锁环节,因为此时已经有对象了不需要再创建对象,直接返回即可。

第二个 if 判定的是是否要创建对象


讲解第6行:(volatile 禁止代码重排序)

讲解第13行:(此处的new 操作又可拆成三个大的步骤,而这三个步骤可能会发生代码重排序。比如步骤1 2 3 =》 1 3 2 ,为了防止这种情况,使用了 volatile)

1、申请一段内存空间

2、在这个内存上调用构造方法,创建出这个实例

3、把这个内存地址赋值给 Instance 引用变量

2、阻塞队列

阻塞队列(BlockingQueue),顾名思义,就是一个队列。阻塞队列是基于普通队列做出的扩展。

基于阻塞队列实现的服务器程序叫消息队列(message queue,mq)

阻塞队列的特点有以下两点:

1、线程安全

2、具有阻塞特性

a)如果针对一个已经满了的队列进行入队列,此时入队列操作就会阻塞,一直阻塞到队列不满(其他线程出队列元素)之后。

b)如果针对一个已经空了的队列进行出队列,此时出队列操作就会阻塞,一直阻塞到队列不空(其他线程入队列元素)之后。

 基于阻塞队列,就可以实现“生产者消费者模型”。

1、生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题

【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列,java,单例模式,开发语言,多线程,笔记

2、削峰填谷,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。【类似于现实中三峡大坝所承担的作用】

【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列,java,单例模式,开发语言,多线程,笔记

 类似于擀饺子皮和包饺子的过程,擀饺子皮的线程就是生产者,包饺子的线程是消费者,饺子皮擀好之后放到桌子上,包饺子的线程在从桌子上拿饺子皮包饺子。这里的桌子就是起到了“阻塞队列”的效果,由于桌子的存在,擀饺子皮的线程擀的速度快时,可以把多的饺子皮放到桌子上先(而不需要直接递给包饺子的线程)。

2.1、BlockingQueue 阻塞队列数据结构

Java标准库中提供了现成的阻塞队列数据结构 BlockingQueue,另外还有 ArrayBlockingQueue,LinkedBlockingQueue,PriorityBlockingQueue

package thread;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class ThreadDemo28 {
    public static void main(String[] args) throws InterruptedException {
        BlockingQueue<String> queue = new ArrayBlockingQueue<>(100);
        queue.put("aaa");
        String elem = queue.take();
        System.out.println("elem = " + elem);
        elem = queue.take();   //进入阻塞状态
        System.out.println("elem = " + elem);
    }
}

注意:此处的阻塞队列,入队出队操作不再是以前的 offer 和 poll 方法,而是使用带有阻塞功能put 和 take 方法。

【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列,java,单例模式,开发语言,多线程,笔记

【网络原理】TCP 协议中比较重要的一些特性(二)-CSDN博客https://blog.csdn.net/zzzzzhxxx/article/details/136579333?spm=1001.2014.3001.5501【网络原理】TCP 协议中比较重要的一些特性(一)-CSDN博客https://blog.csdn.net/zzzzzhxxx/article/details/136366463?spm=1001.2014.3001.5501JVM 的垃圾回收机制以及垃圾回收算法的详解-CSDN博客https://blog.csdn.net/zzzzzhxxx/article/details/136530845?spm=1001.2014.3001.5501

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!文章来源地址https://www.toymoban.com/news/detail-842678.html

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

如果觉得作者写的不错,求给博主一个大大的点赞支持一下,你们的支持是我更新的最大动力!

到了这里,关于【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 多线程案例-单例模式

    多线程案例-单例模式

    设计模式好比象棋中的\\\"棋谱\\\".红方当头炮,黑方马来跳.针对红方的一些走法,黑方应招的时候有一些固定的套路.按照套路来走局势就不会吃亏. 软件开发中也有很多常见的\\\"问题场景\\\".针对这些问题的场景,大佬们总结出了一些固定的套路.按照这些套路来实现代码,也不会吃亏 单例

    2024年02月04日
    浏览(11)
  • 【多线程初阶】多线程案例之单例模式

    【多线程初阶】多线程案例之单例模式

    本文主要给大家讲解多线程的一个重要案例 — 单例模式. 关注收藏, 开始学习吧🧐 单例模式是一种很经典的设计模式, 那么什么叫做设计模式呢? 设计模式好比象棋中的 “棋谱”. 红方当头炮, 黑方马来跳. 针对红方的一些走法, 黑方应招的时候有一些固定的套路. 按照套路来

    2024年02月14日
    浏览(11)
  • 【多线程案例】单例模式(懒汉模式和饿汉模式)

    【多线程案例】单例模式(懒汉模式和饿汉模式)

    提起单例模式,就必须介绍设计模式,而设计模式就是在软件设计中,针对特殊问题提出的解决方案。它是多年来针对一些常见的问题的解决方法,具有良好的可复用性、可扩展性和可维护性。 标准的设计模式有23种,单例模式就是最常见的一种,其目的是确认一个类只有一

    2024年02月10日
    浏览(11)
  • 多线程案例 | 单例模式、阻塞队列、定时器、线程池

    多线程案例 | 单例模式、阻塞队列、定时器、线程池

    单例模式 单例模式是 设计模式 的一种 什么是设计模式? 设计模式好比象棋中的 “棋谱”,红方当头炮,黑方马来跳,针对红方的一些走法,黑方应招的时候有一些固定的套路,按照套路来走局势就不会吃亏,也就发明了一组\\\"棋谱\\\",称为设计模式 软件开发中也有很多常见

    2024年02月15日
    浏览(14)
  • JavaEE(系列8) -- 多线程案例(单例模式)

    JavaEE(系列8) -- 多线程案例(单例模式)

    目录 1. 设计模式 2. 单例模式 -- 饿汉模式 3. 单例模式 -- 懒汉模式  4. 单例模式(懒汉模式-多线程)  什么是设计模式?         设计模式好比象棋中的 \\\"棋谱\\\". 红方当头炮, 黑方马来跳. 针对红方的一些走法, 黑方应招的时候有一些固定的套路. 按照套路来走局势就不会吃亏

    2024年02月05日
    浏览(10)
  • 【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式

    【JAVA】Java 中什么叫单例设计模式?请用 Java 写出线程安全的单例模式

    🍎 个人博客: 个人主页 🏆 个人专栏: JAVA ⛳️   功不唐捐,玉汝于成 目录 前言 正文 懒汉式(Lazy Initialization): 双重检查锁定(Double-Checked Locking): 结语 我的其他博客 在软件设计中,单例设计模式是一种重要的设计思想,它确保了一个类只有一个实例,并提供了一

    2024年01月15日
    浏览(13)
  • Java多线程基础-8:单例模式及其线程安全问题

    Java多线程基础-8:单例模式及其线程安全问题

    单例模式是经典的设计模式之一。什么是设计模式?代码的设计模式类似于棋谱,棋谱就是一些下棋的固定套路,是前人总结出来的一些固定的打法。依照棋谱来下棋,不说能下得非常好,但至少是有迹可循,不会下得很糟糕。代码的设计模式也是一样。 设计模式,就是软件

    2024年02月05日
    浏览(8)
  • 关于Java中单例模式(饿汉模式和懒汉模式)的简析

    关于Java中单例模式(饿汉模式和懒汉模式)的简析

    目录 一.什么是单例模式 二.饿汉模式和懒汉模式 饿汉模式 代码 懒汉模式 代码 关于多线程安全的问题 如何解决懒汉模式多线程安全问题 双if判断 简单来说,就是我们在程序中通过代码进行限制,在该程序中 只能创建一个对象 因为只能创建一个对象,所以对于我们而言就有两种

    2024年02月10日
    浏览(11)
  • Java 枚举实现单例模式,线程安全又优雅!

    Java 枚举实现单例模式,线程安全又优雅!

    这种DCL写法的优点:不仅线程安全,而且延迟加载。 1.1 为什么要double check?去掉第二次check行不行? 当然不行,当2个线程同时执行getInstance方法时,都会执行第一个if判断,由于锁机制的存在,会有一个线程先进入同步语句,而另一个线程等待,当第一个线程执行了 new Sin

    2024年02月02日
    浏览(12)
  • 关于对Java单例模式的理解与简述

    【版权声明】未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) https://www.cnblogs.com/cnb-yuchen/p/17954739 出自【进步*于辰的博客】 参考笔记一,P28.3、P29.9、P71.1。 目录 1、什么是单例模式? 2、如何实现单例模式? 3、单例模式的两种形式 3.1 形式一:“饿汉式” 3.2 形

    2024年02月03日
    浏览(7)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包