This is one way (not the best!). . .
Code:
class RunwaySection
{
//The plane currently in the section
private Plane mPlane = null;
/// <summary>
/// Locks the runway section - should be called
/// by the plane when it wants to move into the section.
///
/// The method call will block until the plane has
/// successfully acquired the runway
/// </summary>
public void lockRunway(Plane iPlane)
{
lock (this)
{
while (mPlane != null)
{
//The runway section is in use
//by another plane, so block on
//this object.
Monitor.Wait(this);
}
//We have acquired the runway :-)!
mPlane = iPlane;
}
}
/// <summary>
/// Should be called by each plane as it leaves
/// the runway section
/// </summary>
public void unlockRunway()
{
lock (this)
{
//Section is no longer in use
mPlane = null;
//Wake up any planes that are waiting to
//acquire the section of runway
Monitor.PulseAll(this);
}
}
}
There is almost certainly a c# class that implements almost exactly what I have just implemented above, but by going to this level you get to see a little more what is going on. It might look a bit confusing, so I will *attempt* to explain.
1. You have 1 thread per plane (presumably created by a Hanger object?)
2. When a plane wants to move into a runway section it calls lockRunway on that segment, passing itself as the argument. If the segment is not in use, it sets can enter the segment.
If the segment is in use then the thread released the lock on the object and blocks (this is what Monitor.wait does). This thread will be woken up by planes moving out of the runway segment (see 3).
3. When a plane leaves the runway segment it should call unlockRunway. This method sets the plane to null and then wakes up any planes which are blocked trying to obtain that piece of runway (this is what Monitor.PulseAll does). This creates a race condition - if more than 1 plane was blocked they will all be woken up. The first one to be executed will acquire the lock and be able to return from the lockRunway method. The others will all get blocked again - this is why you need the while loop in lockRunway.
This is a lot more low level than you probably need to go (i.e: you can probably make use of some standard library classes instead), but hopefully this gives you an insight into how threading and locking works.
You might want to also note a few things:
- It is up to you to ensure that a plane ALWAYS releases a bit of runway after it moves out of it. This can be an issue if exceotions can be thrown between acquiring and releasing a segment. The solution is normally to use finalize blocks

!
- This implementation is far from perfect. You might want the plane who has been waiting the longest to get priority when all waiting planes are woken up. In this implementation it is just random. You can implement ordering by adding waiting threads to a list, and then only waking up the plane at the head of the list.