我想用队列进行一些测试,并使用Queue.Synchronized查看当有两个线程将东西放入队列时,以及第三个线程读取它时它是如何工作的。它似乎相当简单,但它不能正常工作,我不知道为什么。对我来说可能是一个愚蠢的错误。不过还有一点。
class Program
{
public int this1 = 0;
static void Main(string[] args)
{
Tester test1 = new Tester();
Queue myQ = new Queue();
Tester.myQ = Queue.Synchronized(myQ);
Thread test1_thread = new Thread(new ThreadStart(test1.test1));
Thread test1_thread2 = new Thread(new ThreadStart(test1.test1));
test1_thread.Start();
test1_thread2.Start();
int i = 0;
while (i <= 10)
{
i++;
go_back_here:
try
{
Tester.myQ.Enqueue(40);
Console.WriteLine("did it");
int holding = Convert.ToInt32(Tester.myQ.Dequeue());
Console.WriteLine("reading out {0}: {1}", i);
}
catch
{
//Console.Write("e");
//goto go_back_here;
}
}
Console.ReadLine();
}
}
class Tester
{
public static Queue myQ;
public void test1()
{
int this1 = 0;
while (this1 <= 10)
{
Console.WriteLine("Doing something {0}", this1);
myQ.Enqueue(this1);
Console.WriteLine("(peek) {0}", myQ.Dequeue());
this1++;
}
}
}
通过我自己的测试,我发现两个Tester线程正在将内容加载到队列中。当我的主循环尝试将其取消时,我会收到错误,说队列是空的。我把偷看然后Dequeues放在测试线程中,他们能够很好地显示线程中的东西。
然后我想知道我是否以某种方式从主循环访问错误的队列(OOP不是我的强项,仍在学习它),所以我添加了“Tester.myQ.Enqueue(40);”看看我是否可以粘上一些东西。我的peeks / Dequeues没有显示它,但是,当我添加“did it”写行时它会显示出来。我已经运行了很多次这个程序,主循环中的40只出现在测试线程中打印出Dequeue时“就好了”。从来没有评论过它。
对于这个主题有更多了解的人是否会对正在发生的事情有所了解? (是的,我知道我使用goto是一件很糟糕的事情,我让它滑动,因为这应该是一个简单的测试)
答案 0 :(得分:2)
似乎你最初的问题是你的主线程太快地访问了队列(因为线程开始在同一时间放入其中的东西)。在从主线程中的队列中读取之前,您需要确保线程已完成工作。您可以在检查线程设置的某个全局变量的条件时,通过调用Thread.Join
或者Thread.Sleep
循环来等待它们。没有睡眠或加入的while循环是不够的。
此外,你的“偷看”并不是真正的偷看,因为它实际上删除了该项目。您需要使用Console.WriteLine("(peek) {0}", myQ.Peek());
而不是myQ.Dequeue()
。