In this first chapter from the book The Art of Java by Herbert Schildt and James Holmes, the authors highlight certain features of the Java programming language that separate it from other languages. The chapter also covers: memory management, Java's built-in support for multithreading, Java's approach to exceptions as compared to C++, Java's support of polymorphism, and how bytecode enables Java's "Write Once, Run Anywhere" ability and provides security. (ISBN 0-07-222971-3, McGraw-Hill/Osborne, 2003).
Java’s designers saw early on that the future of programming involved language-level support for multithreaded multitasking. Recall that there are two basic types of multitasking: process-based and thread-based. In process-based multitasking, the smallest schedulable unit is a process.
A process is, essentially, a program that is executing. Thus, process-based multitasking is the feature that allows a computer to run two or more programs at the same time. In thread-based multitasking, a thread is the smallest schedulable unit. A thread defines a path of execution within a program. Thus, one process can contain two or more threads of execution, and a multithreaded program can have two or more parts of itself executing simultaneously.
Although process-based multitasking is mostly a function of the operating system, thread-based multitasking benefits greatly from language-level support. For example, C++, which has no built-in support for multithreaded programming, must rely completely on operating system functions to handle multithreading. This means that to create, begin, synchronize, and end threads requires numerous calls to the operating system. As a result, multithreaded code in C++ is not portable. It also makes multithreading unwieldy in a C++ program.
Because Java builds in support for multithreading, much of what must be done manually in other languages is handled automatically in Java. One of the most elegant parts of Java’s multithreading model is its approach to synchronization. Synchronization is based on two innovative features. First, in Java, all objects have built-in monitors that act as mutually exclusive locks. Only one thread can own a monitor at a given time. The locking feature is turned on by modifying a method with the synchronized keyword. When a synchronized method is called, the object is locked and other threads wanting access to the object must wait.
The second part of Java’s support of synchronization is found in Object, the universal superclass of all other classes. Object declares the following synchronization methods: wait( ), notify( ), and notifyAll( ). These methods support interthread communication. Thus, all objects have built-in support for interthread communication. When used in combination with a synchronized method, these methods allow a high-level of control over the way threads interact.
By making multithreading an easy-to-use, built-in part of the language, Java changed the way that we thought about the fundamental architecture of a program. Before Java, most programmers conceptualized programs as monolithic structures that had a single path of execution. After Java, we think of programs as collections of parallel tasks that interact with one another. This change to parallelism has had a wide-ranging effect on computing, but perhaps its greatest impact has been to facilitate the use of software components.
Remember: this is chapter one of The Art of Java, by Herbert Schildt and James Holmes (McGraw-Hill/Osborne, ISBN 0-07-222971-3, 2003). Check it out at your favorite bookstore today. Buy this book now.