Exercises

Solutions to selected exercises can be found in the electronic document The Thinking in Java Annotated Solution Guide, available for a small fee from www.BruceEckel.com.

Inherit a class from Thread and override the run( )
method. Inside run( ), print a message, and then call
sleep( ). Repeat this three times, then return from
run( ). Put a start-up message in the constructor and override
finalize( ) to print a shut-down message. Make a separate thread
class that calls System.gc( ) and System.runFinalization( )
inside run( ), printing a message as it does so. Make several
thread objects of both types and run them to see what happens.
Experiment with different sleep times in Daemons.java to see what
happens.

[68]Runnable was in Java 1.0, while inner classes were not introduced until Java 1.1, which may partially account for the existence of Runnable. Also, traditional multithreading architectures focused on a function to be run rather than an object. My preference is always to inherit from Thread if I can; it seems cleaner and more flexible to me.

[69] Some examples were developed on a dual-processor Win2K machine that would immediately show collisions. However, the same example run on single-processor machines might run for extended periods without demonstrating a collisionthis is the kind of scary behavior that makes multithreading difficult. You can imagine developing on a single-processor machine and thinking that your code is thread safe, then discovering breakages as soon as its moved to a multiprocessor machine.