C#Threading:竞争条件示例

Geo*_*rge 6 c# multithreading

我正在阅读http://www.mono-project.com/ThreadsBeginnersGuide.

第一个示例如下所示:

public class FirstUnsyncThreads {
    private int i = 0;

    public static void Main (string[] args) {
        FirstUnsyncThreads myThreads = new FirstUnsyncThreads ();
    }

    public FirstUnsyncThreads () {
        // Creating our two threads. The ThreadStart delegate is points to
        // the method being run in a new thread.
        Thread firstRunner = new Thread (new ThreadStart (this.firstRun));
        Thread secondRunner = new Thread (new ThreadStart (this.secondRun));

        // Starting our two threads. Thread.Sleep(10) gives the first Thread
        // 10 miliseconds more time.
        firstRunner.Start ();
        Thread.Sleep (10);
        secondRunner.Start ();
    }

    // This method is being excecuted on the first thread.
    public void firstRun () {
        while(this.i < 10) {
            Console.WriteLine ("First runner incrementing i from " + this.i +
                              " to " + ++this.i);
            // This avoids that the first runner does all the work before
            // the second one has even started. (Happens on high performance
            // machines sometimes.)
            Thread.Sleep (100);
        }
    }

    // This method is being excecuted on the second thread.
    public void secondRun () {
        while(this.i < 10) {
            Console.WriteLine ("Second runner incrementing i from " + this.i +
                              " to " + ++this.i);
            Thread.Sleep (100);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

First runner incrementing i from 0 to 1
Second runner incrementing i from 1 to 2
Second runner incrementing i from 3 to 4
First runner incrementing i from 2 to 3
Second runner incrementing i from 5 to 6
First runner incrementing i from 4 to 5
First runner incrementing i from 6 to 7
Second runner incrementing i from 7 to 8
Second runner incrementing i from 9 to 10
First runner incrementing i from 8 to 9
Run Code Online (Sandbox Code Playgroud)

哇,这是什么?不幸的是,文章中的解释对我来说不够.你能解释一下为什么增量发生在混乱的顺序中吗?

谢谢!

Fra*_*sco 2

当存在多个线程时,同步至关重要。在这种情况下,您会看到两个线程都读取和写入this.i,但没有尝试同步这些访问。由于它们同时修改同一内存区域,因此您会观察到混乱的输出。对 Sleep 的调用是危险的,这种方法会导致某些错误。您不能假设线程总是会在最初的 10 毫秒内发生位移。

简而言之:永远不要使用 Sleep 进行同步:-),而是采用某种线程同步技术(例如锁、互斥体、信号量)。始终尝试使用最轻的锁来满足您的需求......

Joe Duffy 所著的《Windows 上的并发编程》一书是一个有用的资源。