多线程单例模式

这篇具有很好参考价值的文章主要介绍了多线程单例模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1、单例模式

顾名思义,单例模式能保证某个类在程序中只存在唯一一份示例,而不会创建出多个实例。就像java的JDBC编程只需要创建一个单例类DataSourece从这个DataSorce中获取数据库连接。没必要创建多个对象。

单例模式具体实现方式分为“饿汉”和“懒汉”两种。

如何保证一个程序中的单例?

1、人为约定,让大家不去new对象,给大家提供了一个方法,用的时候调用这个方法就行。

2、通过语言自身的语法限制一个类只能存在一个对象。

分析过程:

多线程单例模式,单例模式,java,开发语言

1.1、饿汉模式

代码示例:


/**
 * 单例模式
 */
public class Singleton_Hungry {
    //类的成员变量
    private static Singleton_Hungry instance=new Singleton_Hungry();
    //重写为无参构造方法,修饰符改为私有

    private Singleton_Hungry() {
    }
    //对外提供一个获取成员变量的方法
    public static Singleton_Hungry getInstance(){
        return instance;
    }
}

public class Exe_01 {
    public static void main(String[] args) {
        Singleton_Hungry singleton1=Singleton_Hungry.getInstance();
        Singleton_Hungry singleton2=Singleton_Hungry.getInstance();
        Singleton_Hungry singleton3=Singleton_Hungry.getInstance();
        Singleton_Hungry singleton4=Singleton_Hungry.getInstance();
        //打印类对象
        System.out.println(singleton1);
        System.out.println(singleton2);
        System.out.println(singleton3);
        System.out.println(singleton4);
    }
}

多线程单例模式,单例模式,java,开发语言

1.2、懒汉模式

1.2.1、单线程版

 代码示例:


public class Singleton_Lazy {
    private static Singleton_Lazy instance=null;
    private Singleton_Lazy(){

    }
    public static Singleton_Lazy getInstance(){
        //判断返回的对象是否为空
        if(instance==null){
            //创建对象
            instance=new Singleton_Lazy();
        }
        //返回单例对象
        return instance;
    }
}

public class Exe_03 {
    public static void main(String[] args) {
        //让多线程并发获取单例对象
        for (int i = 0; i < 10; i++) {
            Thread thread=new Thread(() ->{
                //获取单例
                Singleton_Lazy instance=Singleton_Lazy.getInstance();
                System.out.println(instance);
            });
            //启动线程
            thread.start();
        }
    }
}

多线程单例模式,单例模式,java,开发语言

 1.2.2、多线程版

上面的懒汉模式-单线程版的实现是不安全的。

线程安全问题发生在首次创建实例时,如果在多个线程中同时调用getInstance方法,就可能导致创建出多个实例。

一旦实例已经创建好了,后面的多线程环境调用getInstance就不再有线程安全问题了(不再修改instance)。

加上synchronized可以改善这里的线程安全问题

 文章来源地址https://www.toymoban.com/news/detail-516331.html

public static Singleton_DCL getInstance() {
    synchronized (Singleton_DCL.class) {
        //判断返回的对象是否为空
        //第二次判断,如果为空重新创建对象
        if (instance == null) {
            //创建对象
            instance = new Singleton_DCL();
        }
    }
    //返回单例对象
    return instance;
}

代码示例:

 


public class Singleton_Lazy {
    private static Singleton_Lazy instance=null;
    private Singleton_Lazy(){

    }
    public static Singleton_Lazy getInstance(){
        synchronized(Singleton_Lazy.class) {
            //判断返回的对象是否为空
            if (instance == null) {
                //创建对象
                instance = new Singleton_Lazy();
            }
        }
        //返回单例对象
        return instance;
    }
}

public class Exe_03 {
    public static void main(String[] args) {
        //让多线程并发获取单例对象
        for (int i = 0; i < 10; i++) {
            Thread thread=new Thread(() ->{
                //获取单例
                Singleton_Lazy instance=Singleton_Lazy.getInstance();
                System.out.println(instance);
            });
            //启动线程
            thread.start();
        }
    }
}

 

 多线程单例模式,单例模式,java,开发语言

 1.2.3、双重检查锁(Double Check Locker)DCL

多线程版的单例模式还存在一个严重的问题:

1、当变量没有被初始化的时候,第一次创建可能会出现线程安全问题,因为多个 线程都会创建实例对象。

2、一旦实例对象被创建之后,new操作就永远不会执行了,因为获取到的实例不为null。

3、那么这时就不需要去执行加锁操作,而且加锁也是要去系统申请锁资源,如果拿到锁之后只是判断一下实例对象是否为null,如果为null什么也不干,那么锁资源也就拜拜浪费掉了

所以就出现了双重校验锁,线程安全的单例模式

代码示例:


public class Singleton_DCL {
    private volatile static Singleton_DCL instance=null;
    private Singleton_DCL(){

    }
    public static Singleton_DCL getInstance(){
        //第一次判断是否为空,目的是判断是否需要加锁
        if(instance==null) {
            synchronized (Singleton_DCL.class) {
                //判断返回的对象是否为空
                //第二次判断,如果为空重新创建对象
                if (instance == null) {
                    //创建对象
                    instance = new Singleton_DCL();
                }
            }
        }
        //返回单例对象
        return instance;
    }
}

public class Exe_04 {
    public static void main(String[] args) {
        //让多线程并发获取单例对象
        for (int i = 0; i < 10; i++) {
            Thread thread=new Thread(() ->{
                //获取单例
                Singleton_DCL instance=Singleton_DCL.getInstance();
                System.out.println(instance);
            });
            //启动线程
            thread.start();
        }
    }
}

 多线程单例模式,单例模式,java,开发语言

 

 

到了这里,关于多线程单例模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Java 多线程系列Ⅳ(单例模式+阻塞式队列+定时器+线程池)

    设计模式就是软件开发中的“棋谱”,软件开发中也有很多常见的 “问题场景”。针对这些问题场景,大佬们总结出了一些固定的套路。按照这些套路来实现代码可能不会很好,但至少不会很差。当前阶段我们需要掌握两种设计模式: (1)单例模式 (2)工厂模式 概念/特征

    2024年02月09日
    浏览(58)
  • 【Java中23种设计模式-单例模式2--懒汉式2线程安全】

    加油,新时代打工人! 简单粗暴,学习Java设计模式。 23种设计模式定义介绍 Java中23种设计模式-单例模式 Java中23种设计模式-单例模式2–懒汉式线程不安全 通过运行结果看,两个线程的地址值是相同的,说明内存空间里,创建了一个对象。

    2024年02月20日
    浏览(46)
  • 【Java多线程】关于多线程的一些案例 —— 单例模式中的饿汉模式和懒汉模式以及阻塞队列

    目录 1、单例模式 1.1、饿汉模式 2.1、懒汉模式  2、阻塞队列 2.1、BlockingQueue 阻塞队列数据结构 对框架和设计模式的简单理解就是,这两者都是“大佬”设计出来的,让即使是一个代码写的不太好的“菜鸡程序员”也能写出还可以的代码。 设计模式也可以认为是对编程语言语

    2024年03月23日
    浏览(90)
  • 【Java|多线程与高并发】设计模式-单例模式(饿汉式,懒汉式和静态内部类)

    设计模式是一种在软件开发中常用的解决复杂问题的方法论。它提供了一套经过验证的解决方案,用于解决特定类型问题的设计和实现。设计模式可以帮助开发人员提高代码的可重用性、可维护性和可扩展性。 设计模式有很多,本文主要介绍单例模式. 单例模式是一种创建型设

    2024年02月11日
    浏览(55)
  • 【单例设计模式原理详解】Java/JS/Go/Python/TS不同语言实现

    单例模式(Singleton Pattern)属于创建型设计模式,这种模式只创建一个单一的类,保证一个类只有一个实例,并提供一个访问该实例的全局节点。 当您想控制实例数目,节省系统资源,并不想混用的时候,可以使用单例模式。单例有很多种实现方式,主要分为懒汉和饿汉模式

    2023年04月27日
    浏览(93)
  • 【多线程】线程安全的单例模式

    单例模式能保证某个类在程序中只存在 唯一 一份实例, 而不会创建出多个实例,从而节约了资源并实现数据共享。 比如 JDBC 中的 DataSource 实例就只需要一个. 单例模式具体的实现方式, 分成 “饿汉” 和 “懒汉” 两种. 类加载的同时, 创建实例. 注意: 使用 static 修饰 instanc

    2024年02月09日
    浏览(46)
  • 设计模式(单例模式,工厂模式),线程池

    目录 什么是设计模式? 单例模式 饿汉模式 懒汉模式 工厂模式 线程池 线程池种类 ThreadPoolExcutor的构造方法: 手动实现一个线程池  计算机行业程序员水平层次不齐,为了 让所有人都能够写出规范的代码, 于是就有了设计模式, 针对一些典型的场景,给出一些典型的解决方案 单例

    2024年02月11日
    浏览(41)
  • 【Linux学习】多线程——线程池 | 单例模式

    🐱作者:一只大喵咪1201 🐱专栏:《Linux学习》 🔥格言: 你只管努力,剩下的交给时间! 多线程部分的知识讲解到此就告一段落了,现在创建一个线程池来检验一下我们的学习成果。 一种线程使用模式,线程过多会带来调度开销,进而影响缓存局部性和整体性能。 线程池

    2024年02月09日
    浏览(50)
  • 多线程案例-单例模式

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

    2024年02月04日
    浏览(43)
  • 【多线程】单例模式

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

    2024年02月04日
    浏览(23)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包