Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >源码 : 设计模式之单例模式的5种实现

源码 : 设计模式之单例模式的5种实现

原创
作者头像
七七分享
修改于 2020-07-13 02:25:24
修改于 2020-07-13 02:25:24
5030
举报
方式一:饿汉式

代码语言:txt
AI代码解释
复制
package cn.relaxheart.designModel.singleton;

/**
 *
 * @Date: 2019-6-1 0001 15:49
 * @Description: 单例实现方式一:饿汉式单例
 *
 * 1. 饿汉式单例在类加载初始化时就创建了一个静态的对象供外部使用,除非系统重启,否则这个对象不会改变。【线程安全】
 *
 * 2. 私有构造,限制外部类实例化该对象 (事实上通过反射是可以实例化构造方法为私有的类的,那基本上会使所有的Java单例实例失效.)
 * 3. 唯一实例只能通过getInstance()方法获取
 *
 */
public class SingletonModel1 {

    // 1. 私有构造
    private SingletonModel1(){}

    // 2. 私有静态全局变量
    private static SingletonModel1 singletonModel1 = new SingletonModel1();

    // 3. 公有静态工厂方法
    public static SingletonModel1 getInstance(){
        return singletonModel1;
    }
}
方式二:懒汉式

代码语言:txt
AI代码解释
复制
package cn.relaxheart.designModel.singleton;

/**
 *
 * @Date: 2019-6-1 0001 15:55
 * @Description: 单例模式实现方式二:懒汉式(延迟加载)
 *
 * 1. 该方式虽然通过延迟加载实现了单例,但是在多线程环境在会产生多个SingletonModel2实例【非线程安全】
 */

public class SingletonModel2 {

    // 1. 私有构造
    private SingletonModel2(){}

    // 2. 私有静态全局为初始化实例变量
    private static SingletonModel2 singletonModel2 = null;

    public static SingletonModel2 getInstance(){
        if (singletonModel2 == null){
            singletonModel2 = new SingletonModel2();
        }
        return singletonModel2;
    }
}

线程安全问题优化:

代码语言:txt
AI代码解释
复制
package cn.relaxheart.designModel.singleton;

/**
 *
 * @Date: 2019-6-1 0001 15:58
 * @Description: 使用synchronized同步锁 对懒汉式单例优化
 *
 * 1. 方法上加synchroinzed,或者使用同步代码块加同步锁,此方法虽然解决了线程安全问题,但是效率低下。当一个线程想要获取实例,
 * 还需要等待上一个线程释放锁。
 */

public class SingletonModel21 {

    // 1. 私有构造
    private SingletonModel21(){}

    // 2. 私有静态未初始化实例
    private static SingletonModel21 singletonModel21 = null;

    public static SingletonModel21 getInstance(){

        // 等同于 synchronized public static SingletonModel21 getInstance()
        synchronized (SingletonModel21.class){
            if (singletonModel21 == null){
                singletonModel21 = new SingletonModel21();
            }
        }

        return singletonModel21;
    }
}

优化方法前加同步锁影响效率的实现

代码语言:txt
AI代码解释
复制
package cn.relaxheart.designModel.singleton;

/**
 * 
 * @Date: 2019-6-1 0001 16:03
 * @Description: 延迟加载同步锁优化
 *
 * 1. 使用双重检查锁,可以避免整个方法加锁,只对需要加锁的代码块加锁,可提高效率。
 */

public class SingletonModel22 {

    // 1. 私有构造
    private SingletonModel22(){}

    private static SingletonModel22 singletonModel22 = null;

    public static SingletonModel22 getInstance(){
        if (singletonModel22 == null){
            synchronized (SingletonModel22.class){
                if (singletonModel22 == null){
                    singletonModel22 = new SingletonModel22();
                }
            }
        }

        return singletonModel22;
    }
}
方式三:静态内部类

代码语言:txt
AI代码解释
复制
package cn.relaxheart.designModel.singleton;

/**
 * @Author: 王琦 <QQ.Eamil>1124602935@qq.com</QQ.Eamil>
 * @Date: 2019-6-1 0001 16:06
 * @Description: 单例模式实现方式三:静态内部类
 *
 * 1. 静态内部类虽然保证了多线程环境下的线程安全性,但是在遇到序列化对象时,默认方式运行结果实际上是多例的。
 */

public class Singleton3 {

    private static class Singleton3Clss{
        private static Singleton3 singleton3 = new Singleton3();
    }

    public static Singleton3 getInstance(){
        return Singleton3Clss.singleton3;
    }
}
方式四:静态代码块

代码语言:txt
AI代码解释
复制
package cn.relaxheart.designModel.singleton;

/**
 * 
 * @Date: 2019-6-1 0001 16:19
 * @Description: 单例实现方式:静态代码块
 */

public class Singleton4 {

    // 1. 私有构造
    private Singleton4(){}

    private static Singleton4 singleton4 = null;

    static {
        singleton4  = new Singleton4();
    }

    public static Singleton4 getInstance(){
        return singleton4;
    }
}
方式五:内部枚举类

代码语言:txt
AI代码解释
复制
public class SingletonFactory {
    // 内部枚举类
    private enum EnmuSingleton{
        Singleton;
        private Singleton5 singleton;
        //枚举类的构造方法在类加载是被实例化 
        private EnmuSingleton(){
            singleton = new Singleton5();
        }
        public Singleton5 getInstance(){
            return singleton;
        }
    }
    public static Singleton5 getInstance() {
        return EnmuSingleton.Singleton.getInstance();
    }
}
class Singleton5{
    public Singleton5(){}
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
理解Task和和async await
本文将详解C#类当中的Task,以及异步函数async await和Task的关系
ryzenWzd
2020/11/12
2.4K0
理解Task和和async await
C#多线程和异步(二)——Task和async/await详解
  同步和异步主要用于修饰方法。当一个方法被调用时,调用者需要等待该方法执行完毕并返回才能继续执行,我们称这个方法是同步方法;当一个方法被调用时立即返回,并获取一个线程执行该方法内部的业务,调用者不用等待该方法执行完毕,我们称这个方法为异步方法。
zls365
2021/02/26
7.2K0
Thread、ThreadPool、Task、Parallel、Async和Await基本用法、区别以及弊端
ThreadPool是Thread的一个升级版,ThreadPool是从线程池中获取线程,如果线程池中又空闲的元素,则直接调用,如果没有才会创建,而Thread则是会一直创建新的线程,要知道开启一个线程就算什么事都不做也会消耗大约1m的内存,是非常浪费性能的,接下来我们写一个例子来看一下二者的区别:
AI.NET 极客圈
2019/08/14
1.8K0
C#学习笔记 线程同步
多个线程同时操作一个数据的话,可能会发生数据的错误。这个时候就需要进行线程同步了。线程同步可以使用多种方法来进行。下面来逐一说明。本文参考了《CLR via C#》中关于线程同步的很多内容。
乐百川
2022/05/05
5850
.NET 各版本多线程使用原理与实践
多线程编程是现代应用程序开发中的核心技术,尤其是在需要并发处理或提升性能的场景中。本文将以 .NET 各版本为背景,详细探讨多线程技术的发展、底层原理以及实践方法。
Michel_Rolle
2024/11/19
2.1K0
C#13中线程同步的作用域锁
C# 13 引入了新的功能,旨在让编码变得更简单、更高效。其中的一个亮点是通过 System.Threading.Lock 类引入的作用域锁功能。这让线程同步变得更加简单,并减少了多线程程序中的错误。
郑子铭
2025/02/18
650
C#13中线程同步的作用域锁
异步与多线程——c#
异步这概念刚开始接触的时候,不是那么容易接受,但是需要用的地方还真的挺多的,刚学习的时候,也很懵逼走了不少弯路,所以这里有必要总结一下。 msdn文档:https://docs.microsoft.com/en-us/dotnet/standard/asynchronous-programming-patterns/ 官方的简介: *.NET Framework提供了执行异步操作的三种模式: 异步编程模型(APM)模式(也称为IAsyncResult的模式),其中异步操作要求Begin和End方法(例如,BeginWrite和EndWrite异步写入操作)。这种模式不再被推荐用于新开发。有关更多信息,请参阅异步编程模型(APM)。
vv彭
2021/01/07
1.7K0
异步与多线程——c#
【深入浅出C#】章节 9: C#高级主题:多线程编程和并发处理
多线程编程和并发处理的重要性和背景 在计算机科学领域,多线程编程和并发处理是一种关键技术,旨在充分利用现代计算机系统中的多核处理器和多任务能力。随着计算机硬件的发展,单一的中央处理单元(CPU)已经不再是主流,取而代之的是多核处理器,这使得同时执行多个任务成为可能。多线程编程允许开发人员将一个程序拆分成多个线程,这些线程可以并行执行,从而提高程序的性能和响应速度。 为什么多线程在现代应用中至关重要?
喵叔
2023/08/26
4.9K0
C# 多线程编程入门教程
随着硬件性能的提升,尤其是多核CPU的广泛应用,多线程编程已经成为现代软件开发中的核心技能之一。多线程可以让程序在多个核心上并发运行,提高效率和性能。然而,编写多线程程序并不是一件简单的事情,尤其是要处理线程间的同步问题,以避免数据竞争和死锁等问题。
Michel_Rolle
2024/09/23
2.6K0
C#学习笔记 线程同步问题
生产者消费者问题大体是这样的:有几个生产者和几个消费者,共享一个缓冲区。生产者会向缓冲区中添加数据;消费者会从缓冲区中将数据取走。需要处理这两者之间的同步问题。
乐百川
2022/05/05
3600
.NET Thread、Task或Parallel实现多线程的使用总结
多线程是指程序中包含多个执行流,即在一个程序中可以同时运行多个不同的线程来执行不同的任务,也就是说允许单个程序创建多个并行执行的线程来完成各自的任务。
郑子铭
2023/08/30
3360
.NET Thread、Task或Parallel实现多线程的使用总结
浅谈.Net异步编程的前世今生----TPL篇
我们在此前已经介绍了APM模型和EAP模型,以及它们的优缺点。在EAP模型中,可以实时得知异步操作的进度,以及支持取消操作。但是组合多个异步操作仍需大量工作,编写大量代码方可完成。
独立观察员
2022/12/06
4710
浅谈.Net异步编程的前世今生----TPL篇
C# dotnet 自己实现一个线程同步上下文
昨天鹏飞哥问了我一个问题,为什么在控制台程序的主线程等待某个线程执行完成之后回来,是在其他线程执行的。而 WPF 在等待某个线程执行完成之后,可以回到主线程执行。其实这是因为在 WPF 和 WinForms 和 ASP.NET 框架里面都自己实现了线程同步上下文,通过线程同步上下文做到调度线程执行。本文就来和小伙伴聊一下如何自己实现一个线程同步上下文
林德熙
2020/05/12
1.1K0
C# 中的线程与任务 — 有什么区别?
在C#编程中,类(class)是一种让我们可以同时执行任务的方式,允许我们在程序的其他部分继续运行时执行代码。尽管现代C#开发人员通常使用Task来管理并发性,但Thread类提供了更多的线程行为控制,这使得它在需要进行低级别线程操作时非常有用。
郑子铭
2025/01/07
1760
C# 中的线程与任务 — 有什么区别?
为什么 Random.Shared 是线程安全的
在多线程环境中使用 Random 类来生成伪随机数时,很容易出现线程安全问题。例如,当多个线程同时调用 Next 方法时,可能会出现种子被意外修改的情况,导致生成的伪随机数不符合预期。
newbe36524
2023/08/23
2830
c#线程-线程同步
如果有多个线程同时访问共享数据的时候,就必须要用线程同步,防止共享数据被破坏。如果多个线程不会同时访问共享数据,可以不用线程同步。 线程同步也会有一些问题存在: 1、性能损耗。获取,释放锁,线程上下文建切换都是耗性能的。 2、同步会使线程排队等待执行。
苏州程序大白
2021/08/13
7700
从 ThreadLocal 到 AsyncLocal
前些天跟大佬们在群里讨论如何在不使用构造函数,不增加方法参数的情况下把一个上下文注入到方法内部使用,得出的结论是 AsyncLocal 。感叹自己才疏学浅,居然才知道有 AsyncLocal 这种神器。于是赶紧恶补一下。
MJ.Zhou
2021/11/18
5540
C#多线程(14):任务基础②
上一篇,我们学习了任务的基础,学会多种方式场景任务和执行,异步获取返回结果等。上一篇讲述的知识比较多,这一篇只要是代码实践和示例操作。
痴者工良
2021/04/26
7390
使用C#封装一个多线程测试工具
这个工具可以帮助开发者测试多线程程序的性能、线程安全性和并发问题。我们将实现以下功能:
软件架构师Michael
2025/01/24
1080
[C#] Task.CompletedTask和Task.Result什么时候用?
在学习C#中的Task方法时,可以知道Task启动一个异步线程方法可以用Task.Run()进行,具体可以参看附录部分。
科控物联
2023/09/01
2.2K0
[C#] Task.CompletedTask和Task.Result什么时候用?
相关推荐
理解Task和和async await
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档