为什么 C# 单例类有时会在多线程中调用两个方法?

宙斯

我在多线程环境中遇到了我的单例类问题。此示例程序在单独的线程上调用方法 A 和 B。通常这可以正常工作。

在某些情况下,如底部的最后一个结果所示

  • 方法调用开始
  • 方法 B 调用开始
  • 方法 B 调用结束
  • 然后方法 A 调用结束<----为什么会发生这种乱序?

这是因为我没有执行双锁吗?我如何确保这不会发生?

呼叫者

class Program
{
    static void Main(string[] args)
    {
            ThreadPool.QueueUserWorkItem(new WaitCallback(CallonThread));
            Singleton.Instance.Test("B");
            Console.ReadKey();

    }

    static void CallonThread(object a)
    {
        Singleton.Instance.Test("A");
    }
}

单例类

public class Singleton
{
    static readonly object Padlock = new object();
    private static Singleton _instance;
    protected Singleton()
    {
    }
    public static Singleton Instance
    {
        get
        {
            lock (Padlock)
            {
                if (_instance == null)
                {
                    _instance = new Singleton();
                }
                return _instance;
            }
        }
    }
    public void Test(string id)
    {
        if (id == "A")
        {
            new Data().MethodA();
        }
        else
        {
            new Data().MethodB();
        }
    }
}

数据类

public class Data
{
    public void MethodA()
    {
        Console.WriteLine("Start Method A");
        Console.WriteLine("End Method A");
    }
    public void MethodB()
    {
        Console.WriteLine("Start Method B");
        Console.WriteLine("End Method B");
    }
}

结果 在此处输入图片说明

布洛格胡德

这将有助于阻止 MethodA 和 MethodB 同时执行:

public class Data
{

    private static object _padlock = new object();

    public void MethodA()
    {
        lock (_padlock)
        {
            Console.WriteLine("Start Method A");
            Console.WriteLine("End Method A");
        }
    }
    public void MethodB()
    {
        lock (_padlock)
        {
            Console.WriteLine("Start Method B");
            Console.WriteLine("End Method B");
        }
    }
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么在Java 8中split有时会在结果数组的开头删除空字符串?

为什么在多线程C或C ++编程中不认为volatile有用?

为什么C ++没有反射?

为什么Relation.size有时会在Rails 4中返回哈希

为什么有时会出现“工作表类的粘贴方法失败”的情况?

为什么打印char有时会在C中打印4个字节的数字

为什么这个多线程代码有时会打印6?

为什么在线程完成之前退出main()时,为什么在C中的多线程应用中出现访问冲突?

C#MediaElement-为什么在切换源后Play()有时会静默失败?

为什么C#对象类具有两个equals方法

为什么Cryptoki.C_OpenSession有时会与HSM断开连接

为什么close_fds = False有时会在Python 2中挂起进程?

为什么在C ++线程函数调用中得到重复的值?

为什么Eclipse CDT代码格式化程序有时会在模板参数中引入空格?

C ++继承-为什么调用父方法?

为什么有时会在终端中反复提示“>”?

为什么C ++函数调用便宜?

为什么读取属性有时会在javascript中引发错误?

调用不访问空对象指针上的数据的方法有时会起作用,有时会崩溃。为什么它不总是崩溃?

为什么grep有时会返回带有两个斜杠的目录?

为什么此C代码中的结构有两个名称?

为什么不调用该函数?C ++

为什么终端有时会回呼诸如^ C之类的特殊字符?

为什么C ++ 17在模板中具有相同目的的两个关键字(类和类型名)

为什么不使用C ++调用Destructor?

为什么 index 有时会在 reduce() 方法中意外运行?

为什么 next() 有时会在生成器上隐式调用?

为什么在 C++ 中的类中拥有一个线程并使用构造函数调用它如此困难?

为什么有时我会溢出,有时不会在 C 中