Thursday, May 31, 2012

Java: "implements Runnable' vs. "extends Thread'


From what time I've spent with threads in Java, I've found these two ways to write threads.




public class ThreadA implements Runnable {
public void run() {
//Code
}
}
//with a "new Thread(threadA).start()" call


public class ThreadB extends Thread {
public ThreadB() {
super("ThreadB");
}
public void run() {
//Code
}
}
//with a "threadB.start()" call



Is there any significant difference in these two blocks of code?


Source: Tips4all

6 comments:

  1. Yes: implements Runnable is the preferred way to do it, IMO. You're not really specialising the thread's behaviour, you're just giving it something to run. That means composition is the philosophically "purer" way to go.

    In practical terms, it means you can implement Runnable and derive from anything else as well.

    ReplyDelete
  2. The caveat is important

    In general, I would recommend using something like Runnable rather than Thread because it allows you to keep your work only loosely coupled with your choice of concurrency. For example, if you use a Runnable and decide later on that this doesn't in fact require it's own Thread, you can just call threadA.run().

    Caveat: Around here, I strongly discourage the use of raw Threads. I much prefer the use of Callables and FutureTasks (From the javadoc: "A cancellable asynchronous computation"). The integration of timeouts, proper cancelling and the thread pooling of the modern concurrency support are all much more useful to me than piles of raw Threads.

    Follow-up: there is a FutureTask constructor that allows you to use Runnables (if that's what you are most comfortable with) and still get the benefit of the modern concurrency tools. To quote the javadoc:


    If you don't need a particular result, consider using constructions of
    the form:

    Future<?> f = new FutureTask<Object>(runnable, null)


    So, if we replace their runnable with your threadA, we get the following:

    new FutureTask<Object>(threadA, null)

    ReplyDelete
  3. Moral of the story : Inherit only if you want to override some behavior.

    or rather it should be read as "Inherit less, interface more"

    ReplyDelete
  4. You should implement Runnable, but if you are running on Java 5 or higher, you should not start it with new Thread but use an ExecutorService instead. For details see: How to implement simple threading in Java.

    ReplyDelete
  5. One thing that I'm surprised hasn't been mentioned yet is that implementing Runnable makes your class more flexible.

    If you extend thread then the action you're doing is always going to be in a thread. However, if you extend Runnable it doesn't have to be. You can run it in a thread, or pass it to some kind of executor service, or just pass it around as a task within a single threaded application (maybe to be run at a later time, but within the same thread). The options are a lot more open if you just use Runnable than if you bind yourself to Thread.

    ReplyDelete
  6. I would say there is a third way:

    public class Something {

    public void justAnotherMethod() { ... }

    }

    new Thread(new Runnable() {
    public void run() {
    instanceOfSomething.justAnotherMethod();
    }
    }).start();


    Maybe this is influenced a bit by my recent heavy usage of Javascript and Actionscript 3, but this way your class doesn't need to implement a pretty vague interface like Runnable.

    ReplyDelete