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>;-)

4

2 回答 2

1

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

为了解决这个问题,卡车需要继续运行,直到所有集装箱都通过管道。例如,您可以在码头上设置一个计数器(例如loadedContainers),并在每次从码头卸下要装载到卡车上的集装箱时递增该计数器。然后return loadedContainers == 100;Kade.HeeftContainers吸气剂中。

于 2012-05-19T10:58:24.650 回答
1

还可以了解 Diagnostics 命名空间...

例如

if(!System.Diagnostics.Debugger.IsAttached)
    if(System.Diagnostics.Debugger.Attach()) System.Diagnostics.Debugger.Break();
于 2012-05-19T12:17:37.000 回答