-1

so I am making a train simulation with multithreading and I have run into a problem. What I want to happen is that a train will stop in a station to let the passengers board the train then after a certain amount of passengers board the train, the train will then depart to the next station and do the same thing and let the passengers board and then go to the next station and so forth. The output that I am getting can be seen below. The train successfully arrives to the next station but it just gets stuck there and never gets any passenger to board the train. I am well aware that this is happening because of the wait() in my code. I would like to ask for your suggestions on what can I do in this kind of situation and would like some guidance to point me to the right direction

The train has arrived at station 1
Passenger has arrived at the station
Passenger is boarding the train
Passenger has arrived at the station
Passenger is boarding the train
Passenger has arrived at the station
Passenger is boarding the train
Passenger has arrived at the station
Passenger is boarding the train
Passenger has arrived at the station
Passenger is boarding the train
The train will now be leaving the station
The train will now be arriving at the next station
The train has arrived at station 2
import java.util.*;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;

public class Main {
    public static void main(String[] args) {
    Station s = new Station();  
    Train t = new Train(s);
    new Thread(t).start();
    passenger p = new passenger(t,s);
    new Thread(p).start();
    
    }
    
    
}
class Train implements Runnable {
    Station s;
    public Train (Station s) {
        this.s = s;
    }
    public void run() {
        s.arriveAtStation();
        
    }
}

class passenger implements Runnable {
    Train t;
    Station s;
    public passenger(Train t, Station s){
        this.t = t;
        this.s = s;
    }
    public void run() {
        s.waitForPassengers(); 
    }
 }

import java.util.concurrent.CountDownLatch;

public class Station {

    int stations = 5;
    int currentStation = 1;
    int npassengers = 0;
    int passengers = 5;
    public synchronized void arriveAtStation() {
        while (currentStation != stations) {
            System.out.println("The train has arrived at station " + currentStation);
            currentStation++;
            try {
                wait();
            } catch (InterruptedException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        if (currentStation == stations) {
            System.out.println("The train has reached the final station");
        }
    }
    public synchronized void waitForPassengers() {
        while(npassengers != passengers) {
            System.out.println("Passenger has arrived at the station");
            try {
                Thread.sleep(1000);
            }
            catch (Exception e) {}
            System.out.println("Passenger is boarding the train");
            npassengers++;
        }
        
        
        System.out.println("The train will now be leaving the station");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        System.out.println("The train will now be arriving at the next station");
        notify();
        
    }
}

Erwin Bolwidt
  • 30,799
  • 15
  • 56
  • 79
  • 1
    You're supposed to mark the correct answer correct, and leave the question to help people in the future. – matt Mar 09 '21 at 11:17

1 Answers1

3

You somehow need to start another Thread Passenger upon arriving at your next station.

Explanation:

Your Train calls arriveAtStation() and blocks by calling wait(). Your Passenger calls waitForPassengers(), increasing passengers by 1 every second until 5. Then it calls notify(), waking up your Train-Thread.

And then it finishes.

Your Train-Thread goes into the second iteration of while (currentStation != stations), calls again wait(). But now there is no more Passenger-Thread running that could call notify() again, because it already finished in the first iteration.


Edit: Some hints for a solution:

  1. Run the Java Thread every X seconds
  2. Executing the Passenger-Thread with some sort of loop in Main
  3. Having the Train-Thread starting another Passenger-Thread

They all might have some pros and cons which might lead you to refine your design.

Sorin
  • 977
  • 3
  • 12
  • Ah that makes sense! Would it be wise to use a for loop for the passenger thread in Main or is there a better way of doing this and ensure the passenger thread keeps running? –  Mar 08 '21 at 22:37