Java并发:试图识别我的乘客来自哪个航班

Java Concurrent: trying to identify my passengers are from which flight

我想在我的项目中找出乘客下船和上船的方法。问题是乘客人数不会按顺序排列,我无法弄清楚哪些航班正在进行这些下机和登机操作。 Objective:想办法给乘客加航班号

package airport_ccp;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;


public class airport_CCP {

    public static void main(String[] args) {
        Random rand = new Random();
                Passengers passsenger = new Passengers();
        
                //runway only got one, two gates
                //runway is exclusive event, remain inclusive event for gates only
                //gates available: 2, so create blockingqueue<runway>(2)
        BlockingQueue<Gate> gates = new ArrayBlockingQueue<Gate>(2);
        
        //threadpool for aircraft, two gates available
                //so create a fixed threadpool for gates with 2 maximum
                ExecutorService threadpool  = Executors.newFixedThreadPool(2);
        
        // 2 active inbound for 2 gates.
        for (int i = 1; i <= 2; i++) {
            gates.add(new Gate(i));
        }
        
          //10 flights
        for(int i = 1; i <= 10; i++) {
            try {
                // 3 secnonds hold for new aircraft
                Thread.sleep(rand.nextInt(3000));
                threadpool.submit(new Aircraft(i, "land", gates));

                 //initial thought of input

                ExecutorService executor = Executors.newCachedThreadPool();
    
                for(int j=0; j<50; j++){
                executor.submit(new Runnable() {
                public void run() {
                Passengers.getInstance().run();
                }
            
                });
                }
                executor.shutdown();
                //input ends
                              
                                
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
                  
                
                
                
        threadpool.shutdown();
        
        try {
            if (threadpool.awaitTermination(100, TimeUnit.SECONDS)) {
                for (int i = 1; i <= 2; i++) {
                    gates.take().printReport();
                }
            }
        } catch (InterruptedException e) {
        }
    }
}

下面是我的乘客class

package airport_ccp;

import java.util.Random;
import java.util.concurrent.Semaphore;

public class Passengers {
    
   private static Passengers instance = new Passengers();
   
   private Semaphore sema = new Semaphore(50, true); //set max to 50
   
   private int passengercount = 0;
   
   private Passengers() {
       
   }
   
   public static Passengers getInstance(){
       return instance;
   }
   
   public void run() {
       
       try {
           
           sema.acquire();
           System.out.println( "MH " /*ID input*/ + " : Passengers " + passengercount + " Disembarking");

       } catch (InterruptedException ex) {
           ex.printStackTrace();
       }
       
       try {
           dorun();
       }
       finally {
       System.out.println( "MH " /*ID input*/ + " : Passengers " + passengercount + " Embarking");
       sema.release();
       }
   }
   
   
   public void dorun() {
       
       synchronized (this) {
           passengercount++;
       }
       
       try {
           Thread.sleep(2000);
       } catch (InterruptedException ex) {
           ex.printStackTrace();
       }
       
       
       synchronized (this) {
           passengercount--;
       }

   }
}

飞机class如果有任何问题

package airport_ccp;

import java.util.Date;
import java.util.Random;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.TimeUnit;

public class Aircraft implements Runnable{
    String status;
    int ID;
         Date arrival;
     BlockingQueue<Gate> gatescount = null;
     Gate gate;
    
    public Aircraft(int ID, String status, BlockingQueue<Gate> gatescount) {
        this.ID = ID;
        this.gatescount = gatescount;
        
        
        System.out.println("\t Time : " + java.time.LocalDateTime.now() + "\t" + " MH " + ID + " is calling for landing.");
    }


    @Override
    public void run() {
            
        try {
                        this.status = "land";
            gate = gatescount.take();
            System.out.println("\t MH " + ID + " has been assigned to " + gate.getName() + ".");
            System.out.println( "\t Time : " + java.time.LocalDateTime.now() + "\t" + " MH " + ID + " is " + status + ".");
                        //Thread.sleep(1000*(1+new Random().nextInt(10)));
                        Thread.sleep(5000);
                        
                        
                        
        } catch (InterruptedException e) {
            e.printStackTrace();
        } 
        gate.inc(status);
                this.status="depart";
        System.out.println("\t Time : " + java.time.LocalDateTime.now() + "\t" + "MH " + ID + " has " + status);
        gatescount.add(gate);
    }

错误 - 为什么不将航班号传入 run 方法?

 // in Passengers
 public void run(int id) {
   
   try {           
       sema.acquire();
       System.out.println( "MH " + id + " : Passengers " + passengercount + " Disembarking");
   } catch (InterruptedException ex) {
       ex.printStackTrace();
   }
   
   try {
       dorun();
   }
   finally {
       System.out.println( "MH " + id + " : Passengers " + passengercount + " Embarking");
       sema.release();
   }
 }

 // when calling Passengers: pass in that ID
 for(int i = 1; i <= 10; i++) {
     try {
       /* ... */
            for(int j=0; j<50; j++){
                int id = i; // <-- copy to a constant value; once assigned, id is never changed
                executor.submit(new Runnable() {
                    public void run() {
                        Passengers.getInstance().run(id);
                    }                    
                });
            }
       /* ... */

注意,之前的版本使用这段代码,会产生错误,因为i的值在每次迭代中都会发生变化,而Java需要保证保持不变;使用不变的引用(如上)解决了问题:

            for(int j=0; j<50; j++){
                executor.submit(new Runnable() {
                    public void run() {
                        Passengers.getInstance().run(i); // <-- fails, because i is not, and cannot be made, final
                    }                    
                });
            }