c# 多线程单例模式_单例模式与多线程

本文深入探讨了C#中单例模式与多线程结合时可能遇到的问题,包括立即加载(饿汉模式)、延迟加载(懒汉模式)及其线程安全问题。介绍了使用DCL双检查锁、静态内置类、序列化与反序列化、静态代码块以及enum枚举实现线程安全的单例模式,并针对序列化攻击提供了解决方案。
摘要由CSDN通过智能技术生成

本章的知识点非常重要,通过单例模式与多线程技术相结合,在这个过程中能发现很多从未考虑的情况,一些不良的程序设计方法如果应用在商业项目中,将会遇到非常大的麻烦。本章的案例也将充分说明,线程与某些技术相结合时要考虑的事情有很多。如何使单例模式遇到多线程是安全的、正确的。

立即加载/饿汉模式

什么是立即加载?立即加载就是使用类的时候已经将对象创建完毕,常见的实现方法就是直接new实例化。而立即加载从中文的语境来看,有着急、急迫的含义,所以也称饿汉模式。

立即加载/ 饿汉模式是在调用方法前,实例已经被创建了。

package com.pro;public class MyObject {
        //立即加载方式==饿汉模式    private static MyObject myObject = new MyObject();    private MyObject(){
        }    public static MyObject getInstance(){
         //此代码版本为立即加载        // 因为getInstall()方法没有同步,所以有可能出现非线程安全问题     return myObject;        }}
public class MyThread extends Thread{
        @Override    public void run() {
            System.out.println(MyObject.getInstance().hashCode());    }}

f824a8e80e7585d4435e64bff24320b4.png

控制台打印的hashCode是同一个值,说明对象是同一个,也就实现了立即加载单例设计模式。

02

延迟加载/懒汉模式

什么是延迟加载?延迟加载就是调用get方法时实例才被创建,常见的实现方法就是get()方法中进行new实例化。~懒汉模式。

package com.pro;public class MyObject {
        //立即加载方式==饿汉模式    private static MyObject myObject;    private MyObject(){
        }    public static MyObject getInstance(){
         if(myObject != null){
         }else {
             myObject = new MyObject();     }     return myObject;    }}

cf53d494f76ba4a835069081a8da6bc2.png

可以看到取得一个对象的实例,但是如果在多线程环境中,就会出现多个实例的情况,与单例模式的初衷相背离的。

03

延迟加载/懒汉模式的缺点

public class MyObject {
        //立即加载方式==饿汉模式    private static MyObject myObject;    private MyObject(){
        }    public static MyObject getInstance(){
            try {
                if (myObject != null) {
                } else {
                    //模拟在创建对象之前做一些准备性工作                Thread.sleep(3000);                myObject = new MyObject();            }        }catch (InterruptedException e){
                e.printStackTrace();        }     return myObject;    }}

989ed06d1014b34ee2ed7ef15feab339.png

控制台打印了3种hashCode,说明创建了3个对象,并不是单例的,这就是错误的单例模式。

04

延迟的加载/懒汉模式的解决方案

  • 方法上加锁

public class MyObject {
        //立即加载方式==饿汉模式    private static MyObject myObject;    private MyObject(){
        }    //设置同步方法效率太低了,整个方法被上锁    synchronized  public static MyObject getInstance(){
            try {
        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值