使用两个在列表中打印数字的线程。但重复的数字很少。我使用信号量锁定哪个不起作用。难道我做错了什么 ?需要帮助!
class Program
{
public static int count=0;
public static List<string> numbers = new List<string>();
public static int semaphore=0;
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
numbers.Add(i.ToString());
}
Console.WriteLine("Before start thread");
Thread tid1 = new Thread(new ThreadStart(MyThread.Thread1));
Thread tid2 = new Thread(new ThreadStart(MyThread.Thread1));
tid1.Start();
tid2.Start();
}
}
public class MyThread
{
public static void Thread1()
{
for (; Program.count < Program.numbers.Count;)
{
if (Program.semaphore != 1)
{
Program.semaphore = 1;
Console.WriteLine(Program.numbers[Program.count]);
Program.count++;
Program.semaphore = 0;
}
}
}
}
答案 0 :(得分:1)
你有竞争条件:
if (Program.semaphore != 1)
并发现它不是1. if (Program.semaphore != 1)
并发现它不是1. if
。要解决此问题,您应该使用lock
:
public class MyThread
{
public static object locker = new object();
public static void Thread1()
{
for (; Program.count < Program.numbers.Count;)
{
lock (locker)
{
if (Program.count < Program.numbers.Count)
{
Console.WriteLine(Program.numbers[Program.count]);
Program.count++;
}
}
}
}
}
请注意,以下天真的解决方案仍然存在竞争条件,并且不起作用:
public class MyThread
{
public static object locker = new object();
public static void Thread1()
{
for (; Program.count < Program.numbers.Count;)
{
lock (locker)
{
Console.WriteLine(Program.numbers[Program.count]);
Program.count++;
}
}
}
}
那是因为for
循环中的检查是在锁外部完成的,因此Program.count
循环中for
循环中的检查之间的另一个线程可能会增加lock
{ {1}}正在输入。