Creating a thread

Written by Sean R. Owens (sean at guild dot net). Share and enjoy. http://darksleep.com/player
For other fine writings on Java and other subjects, check out notablog at http://darksleep.com/notablog

Preface

This is going to be a superfast example of "how to use threads". In particular I going to completely skip over a very very very VERY important subject in these examples, which is that any time you have more than one thread, you have to be very careful about how two (or more) threads access data at the same time. Once you've looked at these examples, immediately go google on "java syncronization" and read everything you can. It is a tricky subject and it is very easy to get it wrong.

Introduction

There are two ways to create a thread, and sadly it seems like people usually choose the wrong one. The wrong way (almost always) is to create a class that subclasses (i.e. extends) Thread. You should only do this if you're creating a new kind of thread, i.e. you want to extend Thread's behavior. The right way is to implement Runnable.

The right way - implement Runnable

The right way to create a thread is to create a class that implements the java.lang.Runnable interface. Runnable is a very simple interface with one method signature, "void run()". When you hand your runnable to a thread, run() is called once. When run() returns the thread exits.
public class ThreadExample1 implements Runnable {
    private Thread myThread;

    // note,'stopping' is declared volatile so we don't have to
    // synchronize when we want to set it true.
    private volatile boolean stopping = false;

    public ThreadExample1() {
        myThread = new Thread(this);
    }

    public void start() {
        stopping = false;
        myThread.start();
    }

    // to stop the thread - myThread has a stop() method but you're not
    // supposed to use it.  Why?  In short, when a thread is stopped it releases
    // all of it's monitors (locks) in a somewhat random manner, which is bad and
    // can lead to both utter chaos and/or very subtle and hard to find bugs.
    // For more on why, see;
    // http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
    public void stop() {
        stopping = true;
    }

    public void run(){
        while(!stopping) {
            // do some work
        }
    }
}

The (usually) wrong way - extend Thread

You should generally only extend Thread when you want to make a new kind of thread, i.e. you want to extend Thread's behavior. But people often do this to create theads, so you should probably know what it looks like. Thread already implements Runnable, so when you extend Thread you override "void run()".
public class ThreadExample2 extends Thread {
    // note,'stopping' is declared volatile so we don't have to
    // synchronize when we want to set it true.
    private volatile boolean stopping = false;

    public ThreadExample2() {
        super();
    }

    public void start() {
        super.start();
        stopping = false;
    }

    // to stop the thread - myThread has a stop() method but you're not
    // supposed to use it.  Why?  In short, when a thread is stopped it releases
    // all of it's monitors (locks) in a somewhat random manner, which is bad and
    // can lead to both utter chaos and/or very subtle and hard to find bugs.
    // For more on why, see;
    // http://download.oracle.com/javase/1.4.2/docs/guide/misc/threadPrimitiveDeprecation.html
    //
    // Also note, we can't name this method stop(), as that would override Thread.stop(), and
    // since Thread.stop() is declared final, it cannot be over ridden.
    public void stopThread() {
        stopping = true;
    }

    public void run(){
        while(!stopping) {
            // do some work
        }
    }
}

Implementing Runnable or extending Thread with an anonymous inner class

You may often see people implement Runnable or extend Thread with an anonymous inner class. This seems to often be done with very short lived threads. (Also, you may see an anonymous Runnable not surrounded by "new Thread().start", used in calls to Swing's EventQueue.invokeAndWait() or EventQueue.invokeLater().)
public class ThreadExample3 {

    public ThreadExample3() {
        // right way
        new Thread(new Runnable() {
            public void run() {
                // Do some work
            }
            }).start();

        // wrong way - but, eh, who really cares?
        new Thread() {
            public void run() {
                // Do some work
            }
        }.start();
    }

}

Last modified: Thu Feb 3 21:15:45 EST 2011