Case study

A bus service travels between a series of equidistant bus stops numbered 1, 2, 3, 4, 5, as in Figure 3. When the bus arrives at either end of its route (stop 1 or stop 5) it turns around and goes back the other way, and continues to do this until it is no longer required. The direction from stop 1 to stop 5 is called the UP direction; the other way is the DOWN direction.

UP -> <- DOWN
1_________2_________3_________4_________5

Passengers arrive at a departure bus stop, wait for a bus that is going in the correct direction and when the bus arrives they get on, travel to their destination stop and get off.

The bus waits at each stop for a fixed amount of time, to allow passengers to get on or off, then the doors are closed and it moves off to the next stop. The bus has a maximum capacity so, if it is full, some waiting passengers may not be able to get on.

The supplied skeleton code ignores the fact that passengers want to travel in a particular direction (UP or DOWN). This means that passengers may actually travel the wrong way for part of the time before eventually reaching their destination. In due course you will rectify this.

A skeleton of a concurrent application that simulates such a system is provided in the NetBeans project BusService which consists of the following classes.

Class Passenger simulates each passenger as a separate thread. Passengers have unique IDs (so that their behaviour can be traced) and they wish to move from a departure bus stop to a destination bus stop. The ID and both stops are given to the constructor. All a passenger thread does is to board the bus at the start bus stop and exit it at the destination bus stop.

Class Bus simulates the bus, which is a resource shared by passengers and the control system. It provides three methods. Methods getOn and getOff are called by the passengers, giving as argument the departure and destination bus stop, respectively. Method move is called by the control system whenever the waiting time has elapsed and the bus has to move to the next bus stop.

Class Control represents the bus control system as a thread. The control system basically keeps repeating two steps – wait a fixed amount of time and move the bus one stop in the appropriate direction – until all passengers have arrived at their destination bus stops.

Class Main brings everything together. It declares some constants representing the various parameters of the simulation (waiting time at each bus stop, number of passenger threads etc.). Although these parameters can be changed, you should retain the existing values until you are confident that you have the application working correctly. You have to add code so that the main application thread first creates the control and passenger threads and then waits for all passenger threads to terminate, at which point it tells the control thread that it should terminate too.

The expected output for the partly implemented application would look similar to Figure 2. The lines show the ordering of events, and events happening at the same bus stop are aligned vertically. In the example, the bus has the capacity for two passengers (shown by a dot for each empty seat and an asterisk for each passenger in the bus). Passengers get off two bus stops after the bus stop where they get on (though sometimes they start off going in the wrong direction).

Bus Stops
1---------------2---------------3---------------4---------------5
[..]BUS> arrives
P1 arrives
P1 gets on
P2 arrives
P4 arrives
P6 arrives
P5 arrives
P3 arrives
[*.]BUS> leaves
[*.]BUS> arrives
P2 gets on
[**]BUS> leaves
[**]BUS> arrives
P1 gets off
P4 gets on
[**]BUS> leaves
[**]BUS> arrives
P2 gets off
[*.]BUS> leaves
[*.]BUS> arrives
P6 gets on
P6 gets off
P4 gets off
[..]BUS> leaves
[..]BUS> arrives
[..]BUS> leaves
[..]BUS> arrives
P3 gets on
[*.]BUS> leaves
[*.]BUS> arrives
P5 gets on
[**]BUS> leaves
[**]BUS> arrives
P3 gets off
P5 gets off

Figure 2 Output from running the partially implemented application

Activities and deliverables

  • Add code to the main method of class Main to create threads for six passengers and set them running. Each passenger should be intending to travel two stops along with half of the total number going in the UP direction and the rest in the DOWN direction. The first three passengers should depart from stops 1, 2 and 3 respectively and get off two stops away in the UP direction. The other three passengers should depart from stops 3, 4 and 5 respectively and get off two stops away in the DOWN direction.
  • On running the application, you will notice that the output from your program does not resemble the expected output as shown above. You may see instances of passengers getting on and off the bus well before it has even arrived at their bus stop! Interrupt the application using the Run | Stop Build/Run command and proceed as follows.
    • The methods getOn and getOff are used by passenger threads. A passenger can only get on if the bus arrives at their departure bus stop and there is space on the bus. For the moment you can ignore the direction of travel of the bus. A passenger can only get off if the bus arrives at their destination bus stop.
    • The method move is used by the control thread, which is responsible for moving the bus from the current stop to the next stop. Only the arrival of the bus at a bus stop should release passengers waiting to get on or off there.
  • Run the project and include a screenshot of the NetBeans output window at this stage.
  • Explain the observed behaviour in your output window. Include in your explanation whether passengers enter and exit the bus in any particular order and what happens when the bus arrives at a bus stop. You should have observed that a passenger may fail to board when the bus arrives at their start bus stop, even though there is space on the bus for them to do so. (For example, at stop 4 P5 is waiting. When the bus arrives and P2 gets off, P5 could get on but doesn't at that point and the bus leaves with an empty seat.) Explain why this is, suggest how it could be avoided, and make the necessary changes to the code.
  • At the moment the application runs continuously, using the while loop in class Control, and can only be stopped manually through the IDE, as stated above. It would be better if each passenger thread could signal to the main thread when they have finished, so that the main method can coordinate the stopping of the application as a whole.
  • At present, passengers try to get on the bus even if it is travelling in the wrong direction (e.g. passenger 4 in Figure 2). Modify the code of the getOn method of class Bus and any other code you think necessary in other methods or classes, so that passengers only get on when the bus is travelling in the direction they want to go. Run the application and check that there are no longer any cases of passengers travelling in the wrong direction – you do not need to carry out exhaustive testing.
  • Discuss what the thread safety level of class Bus is, before and after you made the changes.
Academic Honesty!
It is not our intention to break the school's academic policy. Posted solutions are meant to be used as a reference and should not be submitted as is. We are not held liable for any misuse of the solutions. Please see the frequently asked questions page for further questions and inquiries.
Kindly complete the form. Please provide a valid email address and we will get back to you within 24 hours. Payment is through PayPal, Buy me a Coffee or Cryptocurrency. We are a nonprofit organization however we need funds to keep this organization operating and to be able to complete our research and development projects.