Typically, several programs may be executing on a computer at one time. Suppose you are working on your laptop and it is connected to a printer and a modem. One program on your computer could be printing something, another one could be faxing a file, a third could be computing something in the background (perhaps you are on the team to crack an RSA code), and a fourth could be some game that you are playing. Thus, (at least) four programs are executing at the same time on your laptop. Each is called an execution thread.
There is only one CPU (central processing unit) on your computer, so the four programs are not really executing simultaneously. Instead, your computer allocates a bit of execution time to each of these threads, giving each a turn. Your operating system uses some sort of allocation scheme to decide which thread should be the next to execute and how much time it should get. This switching is so fast and frequent that it gives the illusion of simultaneous execution.
These threads (of execution) can be independent (e.g. the printer program and your game don't interact), in which case allocation is fairly easy.
But sometimes, threads have to communicate with each other and perhaps synchronize in some fashion. For example, one thread may be responsible for maintaining windows on the screen, so when your Java program -- which has at least one thread of execution -- draws something in a window, behind the scenes it communicates with the thread that maintains the window.
In Java, synchronization is provided using three features. Suppose c is a class instance that is a thread. Then, execution of c.wait() in another thread b (say) tells the system to stop executing thread b until thread c executes a statement notifyAll. In other words, execution of c.notifyAll tells all threads that are waiting on c that they can now continue.
There is also a ``synchronize'' property, which can be attached to methods or to individual statements; it says that all other processes must be deterred from executing code in this class until this method or statement has finished -- other processes are locked out.
Java provides facilities for declaring and using different threads of execution. We make use of this facility in our cruise control simulation. Each of the five components mentioned in Sect. 6 is a separate thread. And there is a sixth thread, the main program itself, which controls the five components.
So, in our Java simulation, we really have six programs --or six threads of execution-- executing simultaneously.
[Note: You are not responsible for knowing about threads and how to use them. You will not have to write any code that deals directly with statements to manage and synchronize threads. Threads are discussed here because our program needs them and because you should be familiar with the concept of parallel execution -- of having several threads executing simultaneously. Nevertheless, this background will give you some understanding of the code in this program and also should enlighten you a bit on an important topic in computer science, distributed computing.]