Threads may be seen as methods that execute at "the same time" as other methods. Normally, we think sequentially when writing a computer program. From this perspective, only one thing executes at a time. However, with today's multi-core processors, it is possible to literally have several things going on at the very same time while sharing the same memory. There are lots of ways that this is done in the real world, and this chapter goes over them in a way that you can apply to your own projects.
14.3 From the Java Library: java.
Forcing Threads to Sleep
The Thread.sleep() and Thread.yield() methods also provide
some control over a thread’s behavior. When executed by a thread, the
yield() method causes the thread to yield the CPU, allowing the thread scheduler to choose another thread. The sleep() method causes the
thread to yield and not to be scheduled until a certain amount of real time
has passed.
The sleep() method can halt a running thread for a given number of milliseconds, allowing other waiting threads to run. The sleep() method
throws an InterruptedException, which is a checked exception. This
means that the sleep() call must be embedded within a try/catch
block or the method it’s in must throw an InterruptedException.
Try/catch blocks were covered in Chapter 10.
For example, consider the following version of the NumberPrinter.run():
In this example, each thread is forced to sleep for a random number of
milliseconds between 0 and 1,000. When a thread sleeps, it gives up the
CPU, which allows one of the other waiting threads to run. As you would
expect, the output we get from this example will reflect the randomness
in the amount of time that each thread sleeps:
As we will see, the sleep() method provides a rudimentary form of
thread synchronization, in which one thread yields control to another.
SELF-STUDY EXERCISES
EXERCISE 14.2 What happens if you run five NumberThreads of equal priority through 2 million iterations each? Run this experiment and note the output. Don’t print after every iteration! What sort of scheduling algorithm (round-robin, priority scheduling, or something else) was used to schedule threads of equal priority on your system?
EXERCISE 14.3 Try the following experiment and note the output. Let each thread sleep for 50 milliseconds (rather than a random number of milliseconds). How does this affect the scheduling of the threads? To make things easier to see, print each thread’s ID after every 100,000 iterations.
EXERCISE 14.4 The purpose of the Java garbage collector is to recapture memory that was used by objects that are no longer being used by
your program. Should its thread have higher or lower priority than your
program?