Years I ago I took a C++ class in which we worked on an Elevator Simulator. We did not write the program; our task was to modify it to be compiled by a different compiler. When I first learned Java, I translated that C++ program to Java and it has been on my website ever since. I have been surprised by its popularity. I get emails about it from time to time from Europe and across the US. But I always thought it would make an interesting problem to make the simulator multi-threaded. Threads are usually used to improve performance, but not in this case. The purpose of multiple threads in this case, is so that each person would act independently of the rest of the program. The same would be true of the elevators. I knew this would be a strain on a single CPU computer but making each person act autonomous would be an interesting challenge. One other change I wanted to make was to improve how elevators were summoned to a floor. In the original program, all elevators got summoned to a floor. When you watch that simulation you can see all the elevators move en masse.
Well, I finally had a little free time and I wrote my multi-threaded elevator simulator. Here is some information about how it works. A person object runs inside a continuous loop, checking its current state and deciding what to do next, based on its current state. The states are: walking around outside, working, waiting for an elevator, riding in an elevator and taking the stairs. For instance, when a person enters the building they can decide to go to some other floor or work on the first floor. If they decide to work, they work, in computer terms sleep, for some period of time. If they decide to go to another floor, they summon an elevator and then wait. I did use the observer pattern to handle waiting for an elevator and riding on an elevator. For instance, when a person enters an elevator, they 'register' themselves. When an elevator arrives at a floor, it notifies everyone 'registered' with the elevator. It is not an event oriented observer pattern. The elevator just interrupts the 'sleeping' person-threads register with the elevator.
The elevator has two main states stopped and moving. If stopped, the door can be open or closed. Stopped or moving, an elevator can have one of three movement directions, moving up, moving down, no direction.
For me, the hardest part to write was the elevator controller. This object is the one that summons the elevators. Working on it made me curious as to how real systems work. Although the simulator on my website is an JApplet, the program can be run as an Application from the main method in the Simulator class. The applet just calls the Simulator's main method.
The Simulator has a debug flag, which when set to true will create a log file for each person thread, each elevator thread, the controller and each floor. The logger prefix is set to put the logs in c:\logs. You will need to change that if you want them created some where else.
There may be (probably are) some bugs. If you find any please let me know.
2/20/2010 No one has reported any bugs and I know the source files have been downloaded many times. Today, I fixed four bugs, three were the same bug for different objects. When waiting for an elevator, a person can decide to take the stairs. They can do this while the 'floor' is notifying them that the elevator had arrived. This caused an out of index exception and could occur for either waiting up or waiting down. When a person was riding in an elevator, it was possible for a person to 'wakeup' and determine that the elevator had arrived and they would leave the elevator. This could happen while the elevator was notifying the riders that the elevator had arrived. This too could cause an out of index exception. The last bug is in the logging. When I wrote this, I knew that messages were trying to be written after the stream was closed. At the time, I simply caught the exception and sent them to the console. I have fixed this so that any threads still active after log streams are closed, no longer log messages.
2/22/2010 I recently had to move my website. When I did I noticed the bugs mentioned above. I also noticed that the simulator was running very slowly. When I wrote this I was on a single CPU machine. Multi-CPU machines actually run the threads simultaneously and that is when you see the problems. The first thing I noticed was that I was creating a new state object each time I wanted to update the display. Very wasteful!!!. Second, I was synchronizing the getState methods. This was done to get a 'clean' version of the state. This is not necessary because the screen update happens when there is available processing time. Since the display will not always be consistent, it does not matter if the state objects are not 100% consistent. Removing the synchronizing from these two methods greatly improved the performance of the simulator on multi-CPU machines.
You will need the Java plug-in to run this JApplet. If you don't have it you can get it at http://java.com
Elevator Class Diagram
Elevator State Diagram
Person State Diagram
Return to the Java Help Page.
Return to the Davies' home page