Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your developerWorks profile is displayed to the public, but you may edit the information at any time. Your first name, last name (unless you choose to hide them), and display name will accompany the content that you post.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Introduction to Java threads

Brian Goetz (brian@quiotix.com), Consultant, Quiotix
Brian Goetz is a regular columnist on the developerWorks Java technology zone and has been a professional software developer for the past 15 years. He is a Principal Consultant at Quiotix, a software development and consulting firm located in Los Altos, California. See Brian's published and upcoming articles in popular industry publications.

Summary:  The Java thread facility and API is deceptively simple; however, writing complex programs that use threading effectively is not. This tutorial explores threading basics: what threads are, why they are useful, and how to get started writing simple programs that use them. You will also learn about exchanging data between threads, controlling threads, and how threads can communicate with each other.

Date:  26 Sep 2002
Level:  Introductory PDF:  A4 and Letter (388 KB | 27 pages)Get Adobe® Reader®

Activity:  57177 views
Comments:  

A thread's life

Creating threads

There are several ways to create a thread in a Java program. Every Java program contains at least one thread: the main thread. Additional threads are created through the Thread constructor or by instantiating classes that extend the Thread class.

Java threads can create other threads by instantiating a Thread object directly or an object that extends Thread. In the example in Thread basics , in which we calculated as many primes as we could in ten seconds, we created a thread by instantiating an object of type CalculatePrimes, which extends Thread.

When we talk about threads in Java programs, there are two related entities we may be referring to: the actual thread that is doing the work or the Thread object that represents the thread. The running thread is generally created by the operating system; the Thread object is created by the Java VM as a means of controlling the associated thread.


Creating threads and starting threads are not the same

A thread doesn't actually begin to execute until another thread calls the start() method on the Thread object for the new thread. The Thread object exists before its thread actually starts, and it continues to exist after its thread exits. This allows you to control or obtain information about a thread you've created, even if the thread hasn't started yet or has already completed.

It's generally a bad idea to start() threads from within a constructor. Doing so could expose partially constructed objects to the new thread. If an object owns a thread, then it should provide a start() or init() method that will start the thread, rather than starting it from the constructor. (See Resources for links to articles that provide a more detailed explanation of this concept.)


Ending threads

A thread will end in one of three ways:

  • The thread comes to the end of its run() method.

  • The thread throws an Exception or Error that is not caught.

  • Another thread calls one of the deprecated stop() methods. Deprecated means they still exist, but you shouldn't use them in new code and should strive to eliminate them in existing code.

When all the threads within a Java program complete, the program exits.


Joining with threads

The Thread API contains a method for waiting for another thread to complete: the join() method. When you call Thread.join(), the calling thread will block until the target thread completes.

Thread.join() is generally used by programs that use threads to partition large problems into smaller ones, giving each thread a piece of the problem. The example at the end of this section creates ten threads, starts them, then uses Thread.join() to wait for them all to complete.


Scheduling

Except when using Thread.join() and Object.wait(), the timing of thread scheduling and execution is nondeterministic. If two threads are running at the same time and neither is waiting, you must assume that between any two instructions, other threads may be running and modifying program variables. If your thread will be accessing data that may be visible to other threads, such as data referenced directly or indirectly from static fields (global variables), you must use synchronization to ensure data consistency.

In the simple example below, we'll create and start two threads, each of which prints two lines to System.out:

public class TwoThreads {

    public static class Thread1 extends Thread {
        public void run() {
            System.out.println("A");
            System.out.println("B");
        }
    }

    public static class Thread2 extends Thread {
        public void run() {
            System.out.println("1");
            System.out.println("2");
        }
    }

    public static void main(String[] args) {
        new Thread1().start();
        new Thread2().start();
    }
}
          

We have no idea in what order the lines will execute, except that "1" will be printed before "2" and "A" before "B." The output could be any one of the following:

  • 1 2 A B
  • 1 A 2 B
  • 1 A B 2
  • A 1 2 B
  • A 1 B 2
  • A B 1 2

Not only may the results vary from machine to machine, but running the same program multiple times on the same machine may produce different results. Never assume one thread will do something before another thread does, unless you've used synchronization to force a specific ordering of execution.


Sleeping

The Thread API includes a sleep() method, which will cause the current thread to go into a wait state until the specified amount of time has elapsed or until the thread is interrupted by another thread calling Thread.interrupt() on the current thread's Thread object. When the specified time elapses, the thread again becomes runnable and goes back onto the scheduler's queue of runnable threads.

If a thread is interrupted by a call to Thread.interrupt(), the sleeping thread will throw an InterruptedException so that the thread will know that it was awakened by an interrupt and won't have to check to see if the timer expired.

The Thread.yield() method is like Thread.sleep(), but instead of sleeping, it simply pauses the current thread momentarily so that other threads can run. In most implementations, threads with lower priority will not run when a thread of higher priority calls Thread.yield().

The CalculatePrimes example used a background thread to calculate primes, then slept for ten seconds. When the timer expired, it set a flag to indicate that the ten seconds had expired.


Daemon threads

We mentioned that a Java program exits when all of its threads have completed, but this is not exactly correct. What about the hidden system threads, such as the garbage collection thread and others created by the JVM? We have no way of stopping these. If those threads are running, how does any Java program ever exit?

These system threads are called daemon threads. A Java program actually exits when all its non-daemon threads have completed.

Any thread can become a daemon thread. You can indicate a thread is a daemon thread by calling the Thread.setDaemon() method. You might want to use daemon threads for background threads that you create in your programs, such as timer threads or other deferred event threads, which are only useful while there are other non-daemon threads running.


Example: Partitioning a large task with multiple threads

In this example, TenThreads shows a program that creates ten threads, each of which do some work. It waits for them all to finish, then gathers the results.

/**
 * Creates ten threads to search for the maximum value of a large matrix.
 * Each thread searches one portion of the matrix.
 */
public class TenThreads {

    private static class WorkerThread extends Thread {
        int max = Integer.MIN_VALUE;
        int[] ourArray;

        public WorkerThread(int[] ourArray) {
            this.ourArray = ourArray;
        }

        // Find the maximum value in our particular piece of the array
        public void run() {
            for (int i = 0; i < ourArray.length; i++) 
                max = Math.max(max, ourArray[i]);                
        }

        public int getMax() {
            return max;
        }
    }

    public static void main(String[] args) {
        WorkerThread[] threads = new WorkerThread[10];
        int[][] bigMatrix = getBigHairyMatrix();
        int max = Integer.MIN_VALUE;
        
        // Give each thread a slice of the matrix to work with
        for (int i=0; i < 10; i++) {
            threads[i] = new WorkerThread(bigMatrix[i]);
            threads[i].start();
        }

        // Wait for each thread to finish
        try {
            for (int i=0; i < 10; i++) {
                threads[i].join();
                max = Math.max(max, threads[i].getMax());
            }
        }
        catch (InterruptedException e) {
            // fall through
        }

        System.out.println("Maximum value was " + max);
    }
}
          


A thread's life summary

Like programs, threads have a life cycle: they start, they execute, and they complete. One program, or process, may contain multiple threads, which appear to execute independently of each other.

A thread is created by instantiating a Thread object, or an object that extends Thread, but the thread doesn't start to execute until the start() method is called on the new Thread object. Threads end when they come to the end of their run() method or throw an unhandled exception.

The sleep() method can be used to wait for a certain amount of time; the join() method can be used to wait until another thread completes.

3 of 10 | Previous | Next

Comments



Help: Update or add to My dW interests

What's this?

This little timesaver lets you update your My developerWorks profile with just one click! The general subject of this content (AIX and UNIX, Information Management, Lotus, Rational, Tivoli, WebSphere, Java, Linux, Open source, SOA and Web services, Web development, or XML) will be added to the interests section of your profile, if it's not there already. You only need to be logged in to My developerWorks.

And what's the point of adding your interests to your profile? That's how you find other users with the same interests as yours, and see what they're reading and contributing to the community. Your interests also help us recommend relevant developerWorks content to you.

View your My developerWorks profile

Return from help

Help: Remove from My dW interests

What's this?

Removing this interest does not alter your profile, but rather removes this piece of content from a list of all content for which you've indicated interest. In a future enhancement to My developerWorks, you'll be able to see a record of that content.

View your My developerWorks profile

Return from help

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=132382
TutorialTitle=Introduction to Java threads
publish-date=09262002
author1-email=brian@quiotix.com
author1-email-cc=

Tags

Help
Use the search field to find all types of content in My developerWorks with that tag.

Use the slider bar to see more or fewer tags.

Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere).

My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).

Use the search field to find all types of content in My developerWorks with that tag. Popular tags shows the top tags for this particular content zone (for example, Java technology, Linux, WebSphere). My tags shows your tags for this particular content zone (for example, Java technology, Linux, WebSphere).