Java Threads

Excerpt from
Chapter 1: Introduction


Introduction to Threading

This is a book about using threads in the Java programming language and the Java virtual machine. The topic of threads is very important in Java, so important that many features of a threaded system are built into the Java language itself, while other features of a threaded system are required by the Java virtual machine. Threading is an integral part of using Java.

The concept of threads is not a new one: for some time, many operating systems have had libraries that provide the C programmer a mechanism to create threads. Other languages-like Ada-have had support for threads embedded into the language much as the support for threads is built into the Java language itself. Nonetheless, the topic of threads is usually considered a peripheral programming topic, one that's only needed in special programming cases.

With Java, things are different: it is impossible to write all but the simplest Java programs without introducing the topic of threads. And the popularity of Java ensures that many developers who might never have considered learning about threading possibilities in a language like C or C++ need to become fluent in threaded programming.

Java Terms

We'll start by defining some terms used throughout this book. Since Java is a new phenomenon, many terms surrounding it are used inconsistently in various sources; we'll endeavor to be consistent in our usage of these terms throughout the book.

Java
First is the term Java itself. As we know, Java started out as a programming language, and many people today think of Java as being simply a programming language. But Java is much more than just a programming language: it's also an API specification and a virtual machine specification. So when we say Java, we mean the entire Java specification: a programming language, an API, and a virtual machine specification that, taken together, define an entire programming and run-time environment. Often when we say Java, it's clear from context that we're talking about specifically the programming language, or parts of the Java API, or the virtual machine. The point to remember is that the threading features we discuss in this book derive their properties from all the components of the Java environment taken as a whole. So while it's possible to take the Java programming language, directly compile it into assembly code, and run it outside of the virtual machine, such an executable may not necessarily behave the same as the programs we describe in this book.

Virtual machine, interpreters, and browsers
The Java virtual machine is another term for the Java interpreter, which is the code that ultimately runs Java programs by interpreting the intermediate byte-code format of the Java programming language. The Java interpreter actually comes in two popular forms: the interpreter itself (called java) that runs programs via the command line or a file manager, and the interpreter that is built into many popular Web browsers such as Netscape, HotJava, and the appletviewer that comes with the Java Developer's Kit. Both of these forms are simply implementations of the Java virtual machine, and we'll refer to the Java virtual machine when our discussion applies to both. When we use the term java interpreter, we're talking specifically about the command line, standalone version of the virtual machine; when we use the term Java-enabled browser (or, more simply, browser), we're talking specifically about the virtual machine built into these Web browsers.

Programs, applications, and applets
This leads us to the terms that we'll use for things written in the Java language. Generically, we'll call such entities programs. But there are two types of programs a typical Java programmer might write: programs that can be run directly by the Java interpreter and programs designed to be run by a Java-enabled browser. Much of the time, the distinction between these two types of Java programs is not important, and in those cases, we'll refer to them as programs. But in those cases where the distinction is important, we'll use the term applets for programs running in the Java-enabled browser and the term applications for standalone Java programs.

Thread Overview
This leaves us only one more term to define: what exactly is a thread? The term thread is shorthand for thread of control, and a thread of control is, at its simplest, a section of code executed independently of other threads of control within a single program.

Thread of Control

Thread of control sounds like a complicated technical term, but it's really a simple concept: it is the path taken by a program during execution. This determines what code will be executed: does the code in the if block get executed, or does the else block? How many times does the while loop execute? If we were executing tasks from a "to do" list, much as a computer executes an application, what steps we perform and the order in which we perform them is our path of execution, the result of our thread of control.

Having multiple threads of control is like executing tasks from two lists. We are still doing the tasks on each "to do" list in the correct order, but when we get bored with the tasks on one of the lists, we switch lists with the intention of returning at some future time to the first list at the exact point we left off.

Overview of Multitasking

We're all familiar with the use of multitasking operating systems to run multiple programs at one time. Each of these programs has at least one thread within it, so at some level, we're already comfortable with the notion of a thread in a single process. The single-threaded process has the following properties which, as it turns out, are shared by all threads in a program with multiple threads as well:

Now consider what happens when you sit at your computer and start two single-threaded programs: a text editor, say, and a file manager. You now have two processes running on your computer; each process has a single thread with the properties outlined above. Each process does not necessarily know about the other process, although, depending on the operating system running on your computer, there are several ways in which the processes can send each other various messages: a common behavior is that you can drag a file icon from the file manager into the text editor in order to edit the file. So each process runs independently of the other, although they can cooperate if they so choose.

From the point of view of the person using the computer, these processes often appear to execute simultaneously, although there are a lot of variables that can affect that appearance. These variables are dependent on the operating system: for example, a given operating system may not support multitasking at all, so that no two programs appear to execute simultaneously. Or the user may have decided that a particular process is more important than other processes and hence should always run, shutting out the other processes from running and again affecting the appearance of simultaneity.

Finally, the data contained within these two processes is, by default, separated: each has its own stack for local variables, and each has its own data area for objects and other data elements. Under many operating systems, the programmer can make arrangements so that the data objects reside in memory that can be shared between the processes, allowing both processes to access them.

Overview of Multithreading

All of this leads us to a common analogy: we can think of a thread just as we think of a process, and we can consider a program with multiple threads running within a single instance of the Java virtual machine just as we consider multiple processes within an operating system.

So it is that within a Java program, multiple threads have these properties:

Each thread is separated, so that local variables in the methods that the thread is executing are separate for different threads. These local variables are completely private; there is no way for one thread to access the local variables of another thread. If two threads happen to execute the same method, each thread gets a separate copy of the local variables of that method.

Objects and their instance variables can be shared between threads in a Java program, and sharing these objects is much easier between threads of a Java program than sharing data objects between processes in most operating systems. In fact, the ability to share data objects easily between threads is another reason why programming with threads is so useful. But Java threads cannot arbitrarily access each other's data objects: they need permission to access the objects, and one thread needs to pass the object reference to the other thread.

Static variables are the big exception to this analogy: they are automatically shared between all threads in a Java program.

Don't panic over this analogy: the fact that you'll be programming with threads in Java doesn't mean you'll necessarily be doing the system-level type of programming you'd need to perform if you were writing the multitasking operating system responsible for running multiple programs. The Java Thread API is designed to be simple and requires little specialized skill for most common tasks.

Java Threads | O'Reilly Java Center | Copyright 1997, O'Reilly & Associates


O'Reilly Home | Customer Service | About O'Reilly | Contact Us | Search the Catalog |