C#线程共享数据

本文关键字:数据 共享 线程 | 更新日期: 2023-09-27 18:20:47

我需要你的帮助。我刚开始学习线程主题。为什么要打印两次"t2"?

        string text = "t1";
        Thread t1 = new Thread ( () => Console.WriteLine (text) ); 
        t1.Start();   // why do not print 't1'?
        text = "t2";
        Thread t2 = new Thread ( () => Console.WriteLine (text) );
        t2.Start();   // print 't2'

输出:

t2
t2

C#线程共享数据

因为text是共享的,。线程t1可以开始(在后台),并且可以在线程t1可以打印任何内容之前将文本分配给t2。所以两者都打印t2。如果事情发生得足够快,它可能偶尔会打印t1,然后是t2。

由于给出了一个简单的例子,我将给出一个简单解决方案(尽管不太有用):

string text = "t1";
Thread t1 = new Thread(() => Console.WriteLine(text));
t1.Start();   // why do not print 't1'?
t1.Join(); // Wait for thread t1 to finish before continuing
text = "t2";
Thread t2 = new Thread(() => Console.WriteLine(text));
t2.Start();   // print 't2'

不同之处在于,您要等待线程t1完成执行,然后再为text分配一个新值。我只举这个例子说明如何使用Join来等待线程完成。

稍微复杂一点的方法是不使用Lamda表达式。如果你创建了一个静态函数来完成工作,你可以将一个参数(任何类型的object)传递给线程上的Start函数:

    public static void DoPrint(object data)
    {
        Console.WriteLine((String)data);
    }
    static void Main(string[] args)
    {
        string text = "t1";
        Thread t1 = new Thread(DoPrint);
        t1.Start(String.Copy(text)); // Pass a copy of text to Thread and start
        text = "t2"
        Thread t2 = new Thread(DoPrint);
        t2.Start(String.Copy(text)); // Pass a copy of text to Thread and start
    }

请注意,在传入文本数据之前,我们是如何制作文本数据的副本的。这样,即使text = "t2"确实在线程t1打印之前完成,也无关紧要,因为已经传递了副本。如果两条起跑线是:

        t1.Start(text);
        t2.Start(text);

那么,出于同样的原因,我们会遇到与您最初的示例相同的问题。text是一个字符串,而字符串是一个类,因此它们是通过引用传递的。

因为在t1开始工作之前,文本变量赋值给"t2",然后2和t1开始同时工作。