A step by step tutorial teaching you how to create your own chat client and chat server easily in C#, for local networks or the Internet.
A C# tutorial showing you how to make use of WMI to extract information on disk drives, such as model, capacity, sectors and serial number.
This tutorial will teach you how to calculate the shipping cost based on the weight, height, length and depth of the box, the distance and the UPS service type.
Multithreading Fundamentals in Java
This tutorial covers how to create and manage threads in Java's multithreaded environment. It also explains the part that the Runnable interface plays in having classes run inside threads.
On Saturday, May 3rd 2008 at 06:54 PM
By Louis Fernandez (View Profile)
(Rated 3.7 with 81 votes)
Among the defining characteristics of Java is its built-in support for multithreaded
programming. This support, which has been present in Java from the start, is
provided by the Thread class, the Runnable interface, several methods supplied
by Object, and the synchronized keyword. Multithreading enables you to write programs
that contain two or more separate paths of execution that can execute concurrently. Each
path of execution is called a thread. Through the careful use of multithreading, you can
create programs that make efficient use of system resources and maintain a responsive
Because multiple threads can interact in ways that are not always intuitive, adding level of complexity that is not present in a single-threaded program, some programmers avoid multithreading whenever possible. However, the modern programming world is moving toward more use of multithreading, not less. Highly parallel architectures are becoming the norm. Simply put, multithreading will continue to play a critical part in many (perhaps most) real-world applications of Java.
At its core, multithreading is a form of multitasking. There are two distinct types of multitasking: process-based and thread-based. It is important to differentiate between the two. As it relates to this discussion, a process is, in essence, a program that is executing. Thus, process-based multitasking is the feature that allows your computer to run two or more programs concurrently. For example, it is process-based multitasking that allows you to download a file at the same time you are compiling a program or sorting a database. In process-based multitasking, a program is the smallest unit of code that can be dispatched by the scheduler.
In a thread-based multitasking environment, the thread is the smallest unit of dispatchable code. Because a program can contain more than one thread, a single program can use multiple threads to perform two or more tasks at once. For instance, a browser can begin rendering a Web page while it is still downloading the remainder of the page. This is possible because each action is performed by a separate thread. Although Java programs make use of processbased multitasking environments, process-based multitasking is not under the direct control of Java. Multithreaded multitasking is.
All processes have at least one thread of execution, which is called the main thread, because it is the one that is executed when a program begins. From the main thread, you can create other threads. These other threads can also create threads, and so on.
Multithreading is important to Java for two main reasons. First, multithreading enables
you to write very efficient programs because it lets you utilize the idle time that is present
in most programs. Most I/O devices, whether they be network ports, disk drives, or the
keyboard, are much slower than the CPU. Thus, a program will often spend a majority of
its execution time waiting to send or receive information to or from a device. By using
multithreading, your program can execute another task during this idle time. For example,
while one part of your program is sending a file over the Internet, another part can be
The second reason that multithreading is important to Java relates to Java’s eventhandling model. A program (such as an applet) must respond quickly to an event and then return. An event handler must not retain control of the CPU for an extended period of time.
If it does, other events will not be handled in a timely fashion. This will make an application appear sluggish. It is also possible that an event will be missed. Therefore, if an event requires some extended action, then it must be performed by a separate thread.
A thread can be in one of several states. It can be running. It can be ready to run as soon as it gets CPU time. A running thread can be suspended, which is a temporary halt to its execution. It can later be resumed. A thread can be blocked when waiting for a resource. A thread can be terminated, in which case its execution ends and cannot be resumed.
Along with thread-based multitasking comes the need for synchronization, which allows the execution of threads to be coordinated in certain well-defined ways. Java has extensive, integrated support for synchronization, which is achieved through the use of a monitor, which all objects have, and the synchronized keyword. Thus, all objects can be synchronized.
Two or more threads can communicate with each other through methods that are defined by Object. These methods are wait( ), notify( ), and notifyAll( ). They enable one thread to wait on another. For example, if one thread is using a shared resource, then another thread must wait until the first thread has finished. The waiting thread can resume execution when the first thread notifies it that the resource is now available.
There are two basic types of threads: user and daemon. A user thread is the type of thread created by default. For example, the main thread is a user thread. In general, a program continues to execute as long as there is at least one active user thread. It is possible to change the status of a thread to daemon. Daemon threads are automatically terminated when all nondaemon threads have terminated. Thus, they are subordinate to user threads.
Threads can be part of a group. A thread group enables you to manage related threads collectively. For example, you can obtain an array of the threads in the group.
Java’s multithreading system is built upon the Thread class and its companion interface, Runnable. Thread encapsulates a thread of execution. To create a new thread, your program will either implement the Runnable interface or extend Thread. Both Runnable and Thread are packaged in java.lang. Thus, they are automatically available to all programs.
The Runnable Interface
The java.lang.Runnable interface abstracts a unit of executable code. You can construct a thread on any object that implements the Runnable interface. Therefore, any class that you intend to run in a separate thread must implement Runnable. Runnable defines only one method called run( ), which is declared like this:
Inside run( ), you will define the code that constitutes the new thread. It is important to understand that run( ) can call other methods, use other classes, and declare variables just like the main thread. The only difference is that run( ) establishes the entry point for another, concurrent thread of execution within your program. This thread will end when run( ) returns.
Once you have created an instance of a class that implements Runnable, you create a thread by constructing an object of type Thread, passing in the Runnable instance. To start the thread running, you will call start( ) on the Thread object, as described in the next section.
The Thread Class
The Thread class encapsulates a thread. It is packaged in java.lang and implements the Runnable interface. Therefore, a second way to create a thread is to extend Thread and override the run( ) method. Thread also defines several methods that help manage threads. Here are the ones used in this chapter:
Pay special attention to the start( ) method. After an instance of Thread has been created, call start( ) to begin execution of the thread. The start( ) method calls run( ), which is the method defined by Runnable that contains the code to be executed in the thread. This process is described in detail in the following recipes.
Another method of special interest is sleep( ). It suspends execution of a thread for a specified period of time. When a thread sleeps, another thread can execute until the sleeping thread awakes and resumes execution. Several examples in this chapter use sleep( ) to demonstrate the effects of multiple threads.
Thread defines two sets of constructors, one for constructing a thread on a separate instance of Runnable and the other for constructing a thread on classes that extend Thread. Here are the constructors that take a separate instance of Runnable:
Here, thrdObj is a reference to an instance of a class that implements Runnable. This object’s run( ) method contains the code that will be executed as the new thread. The name of thread is passed in thrdName. If no name is specified (or the name is null), then a name is supplied automatically by the JVM. The thread group to which the thread belongs (if any) is passed via thrdGroup. If the thread group is not specified, then the thread group is determined by the security manager (if there is one) or is set to the same group as the invoking thread.
Here are the constructors that create a thread for classes that extend Thread:
The first constructor creates a thread that uses the default name and thread group, as described already. The second lets you specify the name. The third lets you specify the thread group and the name.
For both sets of constructors, the thread will be created as a user thread unless the creating thread is a daemon thread. In this case, the thread will be created as a daemon thread.
There is another Thread constructor that lets you specify a stack size for the thread. However, because of differences in execution environments, the API documentation states that "extreme care should be exercised in its use."
|Digg It! Del.icio.us Reddit StumbleIt Newsvine Furl BlinkList|
Rate this tutorial
Related Source Code
There is no related source code.
Java Job Search