Java:Tutorials:Using threads

From GPWiki
Jump to: navigation, search

In Java it is really easy to create and use multiple threads that are executed in parallel.

However, there's a lot of subtleties in using threads that can cause some nasty problems, especially if multiple threads read and/or write to the same objects/files. There are techniques to avoid such problems, namely synchronization, locks and object locks are often used. That goes beyond the scope of this tutorial. Here we'll only be creating simple threads that run independently and don't interfere with each other.

Recommended Books

Doug Lea's book is THE book on Concurrency (multiple threads) for Java. But it is a tough read for most people. You're best off finding something more consumable, but if you are able to read only the first few chapters of Doug's book then you're on your way to becoming an expert.

The shortcut is to throw "synchronized" on everything and use tools in the IDE to avoid infinitely recursive calls.

See Amazon for the latest titles on "Concurrency" and "Real Time" and "Threads."

Creating a new thread

Creating and running a thread in Java is simple, just follow these steps:

  1. Define a class that implements the Runnable interface. The interface has a single method - called run() - that must be defined.
  2. Place the code that the thread should execute in run(). Remember to handle exceptions.
  3. Create an instance of the class.
  4. Create a Thread object and pass the class instance as the constructor argument.
  5. Call the start() method of the Thread object to start the thread.

An Example

ExampleThread.java

public class ExampleThread extends Thread
{
    private String name;
    private String text;
    private final int REPEATS = 5;
    private final int DELAY = 200;
 
    public ExampleThread( String aName, String aText )
    {
        name = aName;
        text = aText;
    }
 
    public void run()
    {
        try
        {
            for ( int i = 0; i < REPEATS; ++i ) 
            {
                System.out.println( name + " says \"" + text + "\"");
                Thread.sleep( DELAY );
            }
        }
        catch( InterruptedException exception )
        {
            System.out.println( "An error occured in " + name );
        }
        finally
        {
            // Clean up, if necessary
            System.out.println( name + " is quiting..." );
        }
    }
}

ThreadTest.java

public class ThreadTest 
{
    public static void main( String[] args )  
    {
        ExampleThread et1 = new ExampleThread( "Thread #1", "Hello World!" );
        ExampleThread et2 = new ExampleThread( "Thread #2", "Hey Earth!" );
 
        Thread t1 = new Thread( et1 );
        Thread t2 = new Thread( et2 );
 
        t1.start();
        t2.start();
 
        // t1.interrupt();
    }
}

Output

Thread #1 says "Hello World!"
Thread #2 says "Hey Earth!"
Thread #1 says "Hello World!"
Thread #2 says "Hey Earth!"
Thread #1 says "Hello World!"
Thread #2 says "Hey Earth!"
Thread #1 says "Hello World!"
Thread #2 says "Hey Earth!"
Thread #1 says "Hello World!"
Thread #2 says "Hey Earth!"
Thread #1 is quiting...
Thread #2 is quiting...

Be aware that because the threads are running in parallel the output from the threads could be in a different order. In other words; don't count on threads to be running in sync.

If we uncomment t1.interrupt(); in ThreadTest.main() then we notify the thread that it should clean up and terminate. If we do that, then we get the following output.

Thread #1 says "Hello World!"
An error occured in Thread #1
Thread #1 is quiting...
Thread #2 says "Hey Earth!"
Thread #2 says "Hey Earth!"
Thread #2 says "Hey Earth!"
Thread #2 says "Hey Earth!"
Thread #2 says "Hey Earth!"
Thread #2 is quiting...

If you want to check if the interrupt flag is set before it throws an error, then you can write

if ( Thread.currentThread().isInterrupted() ) { // Handle interruption }

inside the try-block.


Have fun using threads!