为什么这段代码有效而不会崩溃

时间:2016-02-13 07:31:22

标签: c# multithreading locking volatile interlocked

我正在学习C#中的volatile,interlock和lock,编写下面的代码来打印奇数和偶数而不使用任何这些同步构造,我运行了几次这段代码并总是给出正确的答案,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace microsoft
{
    class th2_odd_event
    {
        static int num = 1;
        static bool guard = false;
        public void init()
        {
            Thread th = new Thread(print_odd);
            Thread th2 = new Thread(print_even);
            th.Start();
            th2.Start();

        }
        public static void print_odd()
        {
            while (true)
            {
                if (guard == false)
                {
                    if (num % 2 != 0)
                    {
                        Console.WriteLine(num);
                        num++;
                    }

                    guard = true;
                }
                if (num > 20)
                    break;
            }
        }

        public static void print_even()
        {
            while (true)
            {
                if (guard == true)
                {
                    if (num % 2 == 0)
                    {
                        Console.WriteLine(num);
                        num++;
                    }
                    guard = false;
                }

                if (num > 20)
                    break;
            }
        }

    }

此代码如何工作?幸运的是,两个线程之间没有冲突吗?我错过了一些东西......

1 个答案:

答案 0 :(得分:1)

还没有尝试过,但只是通过观察,看起来2个线程只是在循环中运行,如果你认为'guard'变量是lock / mutex变量。

当奇数线程正在运行循环时,逻辑部分被命中,只有当'guard'为假时。在这个时候,偶数线程只是执行一个no-op while循环,因为守卫不是真的。 (如果检查安全,则为只读)

最后,当奇数线程将守卫设置为真时,如果检查将返回false,则它是自己的,如果检查将变为真,则偶数线程将开始打印偶数。

然后循环重复,线程几乎完全工作。 'guard'变量仅在if块的末尾更改,在原子赋值中,因此2个线程不会真正发生碰撞。

这就是你没有遇到任何问题的原因。