Java concurrent: Airport Simulation-如何让飞机同时进入不同的登机口

Java concurrent: Airport Simulation- how to allow planes to access different gates concurrently

我是 Java 话题的新手。我正在设计机场模拟。我想让我的飞机同时进入不同的登机口。 Eg: 当1号位面在1号门时,其他位面可以进入2,3,4号门。

package assignment_self;

import java.util.Random;
import java.util.concurrent.Semaphore;
import java.util.logging.Level;
import java.util.logging.Logger;

class Runway{
    
    static Semaphore capacity = new Semaphore(4);
    
    synchronized void required_to_land(Plane plane) throws InterruptedException
    {
        System.out.println("Plane "+ plane.id + " is requesting to land!");
        System.out.println("Available gates left: " + capacity.availablePermits());
        
        try {
            Thread.sleep(1000);
        } catch (InterruptedException ex) {
            Logger.getLogger(Runway.class.getName()).log(Level.SEVERE, null, ex);
        }
        
        access_runway(plane);
    }
    
    void access_runway(Plane plane) throws InterruptedException
    {
        if(capacity.availablePermits()>0)
        {
            capacity.acquire();
            System.out.println("Plane "+ plane.id+ " had accessed the runway!");
        
            try {
               Thread.sleep(new Random().nextInt(5)*1000);
            } catch (InterruptedException ex) {
               Logger.getLogger(Runway.class.getName()).log(Level.SEVERE, null, ex);
            }
            
            access_gate1(plane);
        }
        else
        {
            System.out.println("ATC: All gateways are occupy! Please wait for a moment Plane "+ plane.id);
        }
    }
    
    void access_gate1(Plane plane) throws InterruptedException
    {
        System.out.println("Plane " + plane.id+ " is landing at gate 1!");
        Thread.sleep(1000);
        System.out.println("Plane " + plane.id+ " is letting passengers down!");
        Thread.sleep(1000);
        System.out.println("Plane "+ plane.id+ " is leaving gate 1!");
        capacity.release();
    }
    
    void access_gate2(Plane plane) throws InterruptedException
    {
        System.out.println("Plane "+ plane.id+ " is landing at gate 2!");
        Thread.sleep(1000);
        System.out.println("Plane " + plane.id+ " is letting passengers down!");
        Thread.sleep(1000);
        System.out.println("Plane "+ plane.id+ " is leaving gate 2!");
        capacity.release();
    }
    
    void access_gate3(Plane plane) throws InterruptedException
    {
        System.out.println("Plane "+ plane.id+ " is landing at gate 3!");
        Thread.sleep(1000);
        System.out.println("Plane " + plane.id+ " is letting passengers down!");
        Thread.sleep(1000);
        System.out.println("Plane "+ plane.id+ " is leaving gate 3!");
        capacity.release();
    }
    
    void access_gate4(Plane plane) throws InterruptedException
    {
        System.out.println("Plane "+ plane.id+ " is landing at gate 4!");
        Thread.sleep(1000);
        System.out.println("Plane " + plane.id+ " is letting passengers down!");
        Thread.sleep(1000);
        System.out.println("Plane "+ plane.id+ " is leaving gate 4!");
        capacity.release();
    }
}

class Plane extends Thread{
    Runway runway;
    int id;
    
    Plane(int id, Runway runway)
    {
        this.id = id;
        this.runway = runway;
    }
    
    @Override
    public void run()
    {
        try {
            runway.required_to_land(this);
        } catch (InterruptedException ex) {
            Logger.getLogger(Plane.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}

public class Assignment_self {

    public static void main(String[] args) {
        // TODO code application logic here
        Runway runway= new Runway();
        
        for(int i=1 ; i<= 10 ; i++)
        {
            Plane p = new Plane(i, runway);
            p.start();
        }
    }
}

这是我当前的输出,一直在运行,我知道错了。

Plane 2 is requesting to land!
Available gates left: 4
Plane 2 had accessed the runway!
Plane 2 is landing at gate 1!
Plane 2 is letting passengers down!
Plane 2 is leaving gate 1!
Plane 10 is requesting to land!
Available gates left: 4
Plane 10 had accessed the runway!
Plane 10 is landing at gate 1!
Plane 10 is letting passengers down!
Plane 10 is leaving gate 1!
Plane 9 is requesting to land!
Available gates left: 4

我想要的输出是这样的。我只是手动输入,所以不是 100% 正确,但这是我希望的概念输出。

Plane 2 is requesting to land!
Available gates left: 4
Plane 2 had accessed the runway!
Plane 2 is landing at gate 1!
Plane 2 is letting passengers down!
Plane 10 is requesting to land!
Available gates left: 3
Plane 10 had accessed the runway!
Plane 10 is landing at gate 2!
Plane 2 is leaving gate 1!
Plane 10 is letting passengers down!
Plane 9 is requesting to land!
Available gates left: 3

非常感谢你们的帮助,因为我已经在这里呆了很长时间了。提前致谢!

获得“可用门”概念的最简单方法是拥有某种 collection 可用门;然后“认领”和“释放”大门 from/to 这个 collection.

例如,您可以这样做:

// A field.
final Deque<Integer> availableGates = new ArrayDeque<>(Arrays.asList(1, 2, 3, 4));

// A method.
OptionalInt claimGate() {
  synchronized (availableGates) {
    if (availableGates.isEmpty()) {
      // You need to handle the possibility of no gates.
      return OptionalInt.empty();
    }

    // Pick a gate from the queue, however you like.
    return OptionalInt.of(availableGates.removeLast());
  }
}

// Another method.
void releaseGate(int gateNumber) {
  // Perhaps you also want to check that this gate number was previously claimed...
  synchronized (availableGates) {
    availableGates.add(gateNumber);
  }
}

现在,在access_runway

void access_runway(Plane plane) {
  OptionalInt maybeGateNumber = claimGate();
  if (!maybeGateNumber.isPresent()) {
    System.out.println("ATC: All gateways are occupy! ...");
    return;
  }

  int gateNumber = maybeGateNumber.get();
  access_gate(plane, gateNumber);
}

access_gate取门号:

void access_gate(Plane plane, int gateNumber) {
  System.out.println("Plane " + plane.id+ " is landing at gate " + gateNumber + "!");
  // ...
  releaseGate(gateNumber);
}