我在想,当我开始我的第一个帖子时,它应该打印"一个+ n"并锁定l,然后在此之后,它应该启动第二个线程并打印"两个+ 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);
}
}
}
}
}
答案 0 :(得分:5)
这部分代码:
l.threadname = "one";
且= "two"
的相应内容未锁定。因此,它们可以随机交错 - 有时字符串"one"
最终会出现在l.threadname
中,有时它会被"two"
覆盖。然后,设法访问lock
函数中的Print
语句的第一个线程完成其工作,另一个线程等待。
最简单的修复,如果您希望它们按顺序运行,则使用lock
关键字包装两个语句,如下所示:
lock (l) { l.threadname = "one"; Print(l); }
(lock
是可重入的,因此lock
中的其他Print
没有问题。
但是,如果它们总是一个接一个地运行,那么使用线程是没有意义的。