2

我正在努力解决多线程问题。

对于简单的任务,我发现最简单的方法是这样做:

new Thread(delegate()
{
    Console.Writeline("doing stuff here");

}).Start();

new Thread(delegate()
{
    Console.Writeline("doing other stuff here");

}).Start();

我想知道的是,如果我在两个线程中调用一个方法,这会导致冲突吗:

new Thread(delegate()
{
    dostuff();

}).Start();

new Thread(delegate()
{
    dostuff();

}).Start();


private void dostuff()
{
    Console.WriteLine("Do Stuff Here");
}
4

3 回答 3

6

dostuff如果您共享变量,它只会导致冲突,例如该方法中这些线程之间的静态类或全局变量。

仅该方法的所有本地变量都是安全的,您可能共享的变量必须使用锁定来防止数据竞争。

此外,如果您希望正确订购控制台,您的控制台也是需要协调才能写入的共享资源。

于 2013-05-08T08:24:24.017 回答
3

原子操作

这种特殊情况不会引起冲突,因为它基本上与第一种情况完全相同(并且因为Console.Writeline 是线程安全的)。只有当他们处理共享对象时,一个例子是:

private int number = 0;

public void RunThreads()
{
    new Thread(delegate()
    {
        Increment();

    }).Start();

    new Thread(delegate()
    {
        Increment();

    }).Start();
}

private void Increment()
{
    number += number;
}

最后,number可能是12取决于线程执行的顺序。这是因为读取number和设置number原子操作(即不是一起读取和设置),因此可能会像这样交错:

Thread1: Read number as 0
Thread2: Read number as 0
Thread1: Set number as 0+1
Thread2: Set number as 0+1

导致number == 1两个线程完成后。

锁定临界区

要解决这样的情况,您可以使用lock关键字创建一个“锁定对象”,以一次只允许一个线程进入该关键部分

private object mylock = new Object();

public void RunThreads()
{
    // ...
}

private void Increment()
{
    lock (mylock)
    {
        number += number;
    }
}

像这样的锁定显然会减慢执行速度,但是因为一次只允许一个线程进入临界区,而其他线程则被阻塞。

于 2013-05-08T08:26:39.190 回答
3

与所有问题一样,答案是-取决于...

这取决于你的 dostuff() 方法内部发生了什么。您正在与 Threadsafe 交互的东西 -这是必读的

您可以像这样在代码中阻塞线程:

var myLock = new object();

然后在线程场景中使用它,例如:

lock(myLock)
{
    // do things in here
}
于 2013-05-08T08:30:03.093 回答