为什么此代码有效而不崩溃

Why this code works and not crashing

我在学习 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;
            }
        }

    }

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

还没有尝试过,但仅通过观察,这 2 个线程似乎只是 运行 独占 while 循环,如果您将 'guard' 变量视为 lock/mutex变量。

当奇数线程运行循环时,逻辑部分命中,只有当'guard'为假时。此时,偶数线程将执行一个无操作的 while 循环,因为守卫不是真的。 (如果检查是安全的,则为只读)

最后,当奇数线程将守卫设置为真时,它自己的 if 检查将 return 假,而偶数线程的 if 检查将变为真,它将开始打印偶数。

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

这就是您可能没有遇到任何问题的原因。