在不同的线程上使用lock关键字

Jam*_*ton 0 c# multithreading

我想当我开始我的第一个线程时,它应该打印"one + n"并锁定l,然后在此之后,它应该启动第二个线程并打印"two + n".

实际发生的是,当我运行程序时,我得到随机结果,有时打印"一个+ n",其他时候打印"两个+ n"

我对此的理解显然有缺陷 - 为什么?

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApplication1
{
class locked
{
    public long numtochange { get; set; }
    public string threadname { get; set; }
}

class Program
{
    public static locked l;

    static void Main(string[] args)
    {
        l = new locked();

        (new Thread(x => { l.threadname = "one"; Print(l); })).Start();


        (new Thread(x => { l.threadname = "two"; Print(l); })).Start();

        Console.ReadLine(); 
    }
    public static void Print(locked l)
    {
        lock (l)
        {
            for (long i = 0; i < 1000; i++)
            {
                l.numtochange = i;
                Console.WriteLine(l.threadname + " " + l.numtochange);
            }
        }    
    }
}
}
Run Code Online (Sandbox Code Playgroud)

Bar*_*zKP 5

这部分代码:

l.threadname = "one";
Run Code Online (Sandbox Code Playgroud)

并且相应的一个= "two"未锁定.因此,它们可以随机交错 - 有时字符串"one"最终l.threadname会被覆盖,有时它会被覆盖"two".然后,管理到函数中的lock语句的第一个线程Print执行其工作而另一个等待.

如果您希望它们按顺序运行,最简单的修复方法是使用lock关键字包装两个语句,如下所示:

lock (l) { l.threadname = "one"; Print(l); }
Run Code Online (Sandbox Code Playgroud)

(lock是折返所以会有与其他没有问题lockPrint).

但是,如果它们总是一个接一个地运行,那么使用线程是没有意义的.

  • 如果你打印出线程id`Console.WriteLine(l.threadname +""+ l.numtochange +""+ Thread.CurrentThread.ManagedThreadId),可以看到这个;` (2认同)