次のことを行う簡単なプログラムを作成しようとしています。
コンテナを船から降ろすクレーンが 2 台あります。彼らはコンテナを波止場に置き、そこで 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>
。使用したい;-)