We live in a world of multiple activities. A person may be talking on the phone while doodling or reading a memo. A fax machine may scan one fax while receiving another and printing a third. We expect the GUI programs we use to be able to respond to a menu while updating the screen. But ordinary computer programs can do only one thing at a time. The conventional computer programming model that of writing one statement after another, punctuated by repetitive loops and binary decision making is sequential at heart.
Sequential processing is straightforward but not as efficient as it could be. To enhance performance, Java offers threading, the capability to handle multiple flows of control within a single application or process. Java provides thread support and, in fact, requires threads: the Java runtime itself is inherently multithreaded. For example, window system action handling and Java's garbage collection that miracle that lets us avoid having to free everything we allocate, as we must do when working in languages at or below C level run in separate threads.
Just as multitasking allows a single operating system to give the appearance of running more than one program at the same time on a single-processor computer, so multithreading can allow a single program or process to give the appearance of working on more than one thing at the same time. With multithreading, applications can handle more than one activity at the same time, leading to more interactive graphics and more responsive GUI applications (the program can draw in a window while responding to a menu, with both activities occurring more or less independently), more reliable network servers (if one client does something wrong, the server continues communicating with the others), and so on.
Note that I did not say " multiprocessing" in the previous paragraph. The term multi-tasking is sometimes erroneously called multiprocessing, but that term in fact refers to the less common case of two or more CPUs running under a single operating system. Actually, multiprocessing is nothing new: IBM mainframes did it in the 1970s, Sun SPARCstations did it in the late 1980s, and Intel PCs did it in the 1990s. True multiprocessing allows you to have more than one process running concurrently on more than one CPU. Java's support for threading includes multiprocessing under certain circumstances, if the operating system and the JVM support it as well. Consult your system documentation for details.
While most modern operating systems POSIX P1003, Sun Solaris, the Distributed Computing Environment (OSF/DCE) for Unix, Windows, and Mac OS provide threads, Java is the first mainstream programming language to have intrinsic support for threaded operations built right into the language. The semantics of java.lang.Object, of which all objects are instances, includes the notion of " monitor locking" of objects, and some methods (notify, notifyall, wait) that are meaningful only in the context of a multithreaded application. Java also has language keywords such as synchronized to control the behavior of threaded applications.
Now that the world has had a few years of experience with threaded Java, experts have started building better ways of writing threaded applications. The Concurrency Utilities, specified in JSR 166 and included in Java for the first time with JDK 1.5, are heavily based on the util.concurrent package by Professor Doug Lea of the Computer Science Department at the State University of New York at Oswego. This package aims to do for the difficulties of threading what the Collections classes (see Chapter 7) did for structuring data. This is no small undertaking, but they seem to have pulled it off. JSR 166 has been discussed as open source (since Professor Lea's package was open source), and a number of experts have worked over the code prior to its inclusion in the JDK.
The java.util.concurrent package includes several main sections:
An implementation of the Executor interface is, of course, a class that can execute code for you. The code to be executed can be the familiar Runnable or a new interface Callable . One common kind of Executor is a "thread pool." A Future represents the future state of something that has been started; it has methods to wait until the result is ready.
These brief definitions are certainly oversimplifications. Addressing all the issues is beyond the scope of this book, but I do provide several examples.