2010-10-17 56 views
1

我想对队列进行一些测试,并使用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++; 
     } 

    } 
} 

通过我自己的测试,我发现两个测试器线程正在将东西加载到队列中。当我的主循环尝试将它出队时,我会收到一个错误,说队列是空的。我把Peeks和Dequeues放在测试线程中,他们能够在线程中显示这些东西。因此我添加了“Tester.myQ.Enqueue(40);”,因此我想知道如果我是从主循环访问错误的队列(OOP不是我的专长,仍在学习它),所以我添加了“Tester.myQ.Enqueue(40);”看看我是否可以在其中插入一些东西。我的peeks/Dequeues没有显示它,但是,当我添加“完成”写入行时,它显示出来了。我已经运行了这个程序了很多次,并且主循环中的40只出现在测试线程打印出来的Dequeue中,当“did it”在那里。从来没有当我评论它。

有人对这个问题有更多的了解可以了解发生了什么吗? (是的,我知道我使用goto是一件可怕的事情,我让它滑动,因为这应该是一个简单的测试)

+0

呃哦,你用了'goto',你是否检查['rapters?](http://xkcd.com/292):) – 2010-10-17 04:45:26

回答

2

看起来你最初的问题是你的主线程也访问队列很快(没有任何内容,因为在同一时间开始在其中放入东西的线程)。在从主线程的队列中读取数据之前,您需要确保线程已完成工作。您可以通过在循环中调用Thread.JoinThread.Sleep进行等待,同时检查线程设置的某个全局变量的条件。没有睡眠或加入的情况下建立一个while循环是不够的。

此外,您的“偷看”不是真正的偷看,因为它实际上删除了该项目。您需要使用Console.WriteLine("(peek) {0}", myQ.Peek());而不是myQ.Dequeue()

+0

嘿,谢谢你的回复。首先只想说,我知道我的Peek实际上并不是一瞥。它最初是,但是后来我把它改成了Dequeue,以确保它可以让一个对象出列。当我改变它的时候,我离开了Console.WriteLine(“(偷看)”),完全没有懒惰。 – cost 2010-10-17 04:01:29

+0

哎呀,没有意识到打进会发布。我不确定您的解决方案是否可以正常工作。我的初始版本的程序在10次迭代后没有停止主循环,如果尝试失败,它将使用goto跳过i ++计数器。该程序会将所有内容放入队列中,然后它会一直运行,不断尝试将队列出队,但它不会工作。无尽循环 – cost 2010-10-17 04:03:46

+0

哈哈,看看这个“Console.WriteLine(”读出{0}:{1}“,i);”东西看起来不对?我忘了把它打印出来的第二个变量,我认为这是把它搞砸了......似乎工作,或者至少比以前好多了。感谢您的帮助,但非常感谢。我在那里插入了一个Thread.Sleep,它可以让我的处理器在循环时避免使用它。 – cost 2010-10-17 04:28:13

相关问题