2012-05-19 20 views
1

我试图做一个简单的程序,执行以下操作:主题似乎从来没有得到一个机会,除非我有一个断点

我有两台起重机是采取关闭集装箱船。他们把集装箱放在码头上,2/3的卡车在那里接货。起重机可以在码头最多放置5个集装箱。

问题如下:当我没有断点时,起重机线程只是挑选容器并将它们放到码头上,然后程序停止。这是每次输出:

Kraan 2 heeft container nummer 1 van het schip gehaald. 
Kraan 2 heeft container nummer 1 op de kade geplaatst. 
Kraan 1 heeft container nummer 2 van het schip gehaald. 
Kraan 1 heeft container nummer 2 op de kade geplaatst. 
Kraan 2 heeft container nummer 3 van het schip gehaald. 
Kraan 1 heeft container nummer 4 van het schip gehaald. 
Kraan 2 heeft container nummer 3 op de kade geplaatst. 
Kraan 2 heeft container nummer 5 van het schip gehaald. 
Kraan 2 heeft container nummer 5 op de kade geplaatst. 
Kraan 1 heeft container nummer 4 op de kade geplaatst. 
Kraan 2 heeft container nummer 6 van het schip gehaald. 
Kraan 1 heeft container nummer 7 van het schip gehaald. 

因此,卡车线程不运行。当我在Wagen.VoerWerkzaamhedenUit()中放置一个断点时,断点确实受到撞击,奇迹般地运行整个程序,直到所有容器都被处理完。

这里是我的代码:

class Program 
    { 
     static void Main(string[] args) 
     { 
      for (int i = 1; i <= 100; i++) 
      { 
       Schip.LaadContainerOpSchip(i); 
      } 

      Thread kraan1 = new Thread(new Kraan().VoerWerkzaamhedenUit); 
      kraan1.Name = "Kraan 1"; 
      kraan1.Start(); 

      Thread kraan2 = new Thread(new Kraan().VoerWerkzaamhedenUit); 
      kraan2.Name = "Kraan 2"; 
      kraan2.Start(); 

      Thread wagen1 = new Thread(new Wagen().VoerWerkzaamhedenUit); 
      wagen1.Name = "Wagen 1"; 
      wagen1.Start(); 

      Thread wagen2 = new Thread(new Wagen().VoerWerkzaamhedenUit); 
      wagen2.Name = "Wagen 2"; 
      wagen2.Start(); 

      kraan1.Join(); 
      kraan2.Join(); 
      wagen1.Join(); 
      wagen2.Join(); 

      Console.WriteLine("Press any key to continue..."); 
      Console.Read(); 
     } 
    } 

public class Kraan 
    { 
     private Random random = new Random(); 

     public void VoerWerkzaamhedenUit() 
     { 
      while (Schip.HeeftContainers()) 
      { 
       Thread.Sleep(random.Next(1000, 6000)); 

       int container = Schip.VerwijderContainer(); 

       if (container != -1) 
       { 
        Console.WriteLine("{0} heeft container nummer {1} van het schip gehaald.", Thread.CurrentThread.Name, container); 

        Thread.Sleep(random.Next(1000, 6000)); 

        Kade.PlaatsContainer(container); 

        Console.WriteLine("{0} heeft container nummer {1} op de kade geplaatst.", Thread.CurrentThread.Name, container); 
       } 
      } 
     } 
    } 

public static class Schip 
    { 
     private static List<int> containers = new List<int>(); 

     public static void LaadContainerOpSchip(int container) 
     { 
      containers.Add(container); 
     } 

     public static int VerwijderContainer() 
     { 
      lock (containers) 
      { 
       int container = -1; 

       if (containers.Any()) 
       { 
        container = containers[0]; 

        containers.RemoveAt(0); 
       } 

       return container; 
      } 
     } 

     public static bool HeeftContainers() 
     { 
      lock (containers) 
      { 
       return containers.Any(); 
      } 
     } 
    } 



public static class Kade 
    { 
     private static List<int> containers = new List<int>(); 

     public static void PlaatsContainer(int container) 
     { 
      lock (containers) 
      { 
       while (containers.Count == 5) 
       { 
        Monitor.Wait(containers); 
       } 

       containers.Add(container); 

       Monitor.PulseAll(containers); 
      } 
     } 

     public static int VerwijderContainer() 
     {  
      lock (containers) 
      { 
       while (containers.Count == 0) 
       { 
        Monitor.Wait(containers); 
       } 

       int container = -1; 

       if (containers.Any()) 
       { 
        container = containers[0]; 

        containers.RemoveAt(0); 
       } 

       Monitor.PulseAll(containers); 

       return container; 
      } 
     } 

     public static bool HeeftContainers() 
     { 
      lock (containers) 
      { 
       return containers.Any(); 
      } 
     } 
    } 

public class Wagen 
    { 
     private Random random = new Random(); 

     public void VoerWerkzaamhedenUit() 
     { 
      while (Kade.HeeftContainers()) 
      { 
       Thread.Sleep(random.Next(1000, 6000)); 

       int container = Kade.VerwijderContainer(); 

       if (container != -1) 
       { 
        Console.WriteLine("{0} heeft container nummer {1} van de kade gehaald.", Thread.CurrentThread.Name, container); 

        Thread.Sleep(random.Next(1000, 6000)); 
       } 
      } 
     } 
    } 

不,我不希望使用阻塞集合,我想用一个List<int> ;-)

+1

你必须住在鹿特丹。问题在于,当kade空着时,工资司机起飞,永不回来。你需要一个更好的退出条件,比如在卡德和船空的时候返回。当凯德有一个容器时,司机也很难入睡。 –

+0

是的,你是对的,我是从那里。我想我会看到你有更好的退出条件,这也是Eren所说的。我需要更好地看看你的司机睡着的提示,但... –

回答

1

程序启动时,卡车检查码头(Kade.HeeftContainers()),然后起重机有机会将集装箱放到码头,以便卡车螺纹立即退出。然后起重机继续填满码头,直至达到5个集装箱的限制。由于卡车螺纹已经退出,所以码头保持满载,以便起重机线程在Monitor.Wait(containers);停止等待。

要解决这个问题,卡车需要继续运行,直到所有的集装箱都通过管道。例如,您可以在码头上有一个柜台(例如loadedContainers),并且每次从码头卸下一个集装箱以便装载到卡车上时,就可以增加此计数器。然后在Kade.HeeftContainers获得者return loadedContainers == 100;

+0

你是对的!我没有想到卡车螺纹可以在起重机螺纹前运行,因此退出了循环回路,这真是愚蠢。更令我震惊的是,这种行为非常一致。我会认为在我运行这个程序的所有时间里,起重机螺纹都会填满码头上的集装箱,所以卡车螺纹可以在它上面工作... –

+0

Right ...所以你说的是,因为码头是空的而船不是,所以程序的首选是从卡车螺纹开始。那很有意思! –

+0

不要介意我以前的评论。我将编辑我的答案,以解释为什么你一直看到相同的结果。 –

1

另请参阅诊断命名空间...

例如,

if(!System.Diagnostics.Debugger.IsAttached) 
    if(System.Diagnostics.Debugger.Attach()) System.Diagnostics.Debugger.Break(); 
+1

我不知道这是什么,所以我会研究它。 –

+0

当你了解并意识到它可能是你最好的朋友,那么你可以投票:) – Jay

+0

是的。你走了! –

相关问题