Categories
implements java java-threads multithreading runnable

“implements Runnable” vs “extends Thread” in Java

2305

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

With implements Runnable:

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

Or, with extends Thread:

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

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

13

  • 65

    Thanks for this question, the answers cleared up a lot of misconceptions I had. I looked into the correct way to do Java threads before SO existed and there was a lot of misinformation/outdated information out there.

    May 8, 2009 at 20:56

  • 5

    there is one reason you might want to extend Thread (but I do not recommend it), you can preemptively handle interrupt(). Again, it’s an idea, it might be useful in the right case, however I do not recommend it.

    – bestsss

    Feb 12, 2011 at 23:23


  • Please see also the answer, nicely explained: stackoverflow.com/q/5562720/285594

    – user285594

    Apr 6, 2011 at 10:06

  • @bestsss, I’m trying to puzzle out what you might mean about handling interrupt(). Are you trying to override the method?

    – Bob Cross

    Apr 25, 2011 at 13:29

  • 8

    yes.As per the code,class Thread A can extend any class whereas class Thread B cant extend any other class

    Jan 27, 2014 at 8:31

1791

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 extend from another class as well… and you can also implement Runnable via a lambda expression as of Java 8.

33

  • 160

    Exactly, well put. What behavior are we trying to overwrite in Thread by extending it? I would argue most people are not trying to overwrite any behavior, but trying to use behavior of Thread.

    – hooknc

    Feb 12, 2009 at 16:50

  • 94

    As a side comment, if you instantiate a Thread and do not call its start() method you are creating a memory leak in Java < 5 (this does not happen with Runnables): stackoverflow.com/questions/107823/…

    Feb 7, 2013 at 13:48

  • 26

    One minor advantage of Runnable is that, if in certain circumstances you don’t care about, or don’t want to use threading, and you just want to execute the code, you have the option to simply call run(). e.g. (very handwavy) if (numberCores > 4) myExecutor.excute(myRunnable); else myRunnable.run()

    Mar 6, 2013 at 19:30

  • 11

    @user949300 you can also do that with extends Thread and if you don’t want threading why would you even implement Runnable

    – m0skit0

    Apr 23, 2013 at 8:15

  • 32

    To paraphrase Sierra and Bates, a key benefit of implementing Runnable is that you are architecturally seperating the “job” from the “runner”.

    Feb 12, 2014 at 9:28

612

tl;dr: implements Runnable is better. However, 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 its 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)

Another option that allows you to stay closer to Runnables is a ThreadPoolExecutor. You can use the execute method to pass in a Runnable to execute “the given task sometime in the future”.

If you’d like to try using a thread pool, the code fragment above would become something like the following (using the Executors.newCachedThreadPool() factory method):

ExecutorService es = Executors.newCachedThreadPool();
es.execute(new ThreadA());

5

  • 44

    This is better than the accepted answer IMHO. One thing: the snippet of code you have doesn’t close down the executor and I see millions of questions where people get this wrong, creating a new Executor every time they want to spawn a task. es would be better as a static (or injected) field so it only gets created once.

    Nov 19, 2012 at 11:27

  • 8

    @artbristol, thanks! I don’t disagree on the new Executor (we do what you suggest in our code). In writing the original answer, I was trying to write minimal code analagous to the original fragment. We have to hope that many readers of these answers use them as jumping off points. I’m not trying to write a replacement for the javadoc. I’m effectively writing marketing material for it: if you like this method, you should see all the other great things we have to offer…!

    – Bob Cross

    Nov 19, 2012 at 13:28

  • 5

    I know I’m a bit late commenting on this, but dealing with FutureTask directly is generally not what you want to do. ExecutorServices will create the appropriate Future for you when you submit a Runnable/Callable to them. Likewise for ScheduledExecutorServices and ScheduledFuture when you schedule a Runnable/Callable.

    – Powerlord

    Apr 28, 2015 at 13:44


  • 3

    @Powerlord, my intention was to make code fragments that matched the OP’s as closely as possible. I agree that new FutureTask isn’t optimal but it is clear for the purposes of explanation.

    – Bob Cross

    Apr 28, 2015 at 17:04

  • in the first paragraph, you mentioned “if you use a Runnable and decide later on that this doesn’t in fact require its own Thread, you can just call threadA.run()”. Do you mean calling runnable.run()? Can you show some code your are referring to?

    – HKIT

    Jul 9 at 9:53


285

Moral of the story:

Inherit only if you want to override some behavior.

Or rather it should be read as:

Inherit less, interface more.

4

  • 1

    This should always be the question if you start making a concurrent running Object! Do you even need the Thread Object funtions?

    – Liebertee

    Oct 21, 2015 at 7:59

  • 7

    When inheriting from Thread, one nearly always wants to override the behavior of the run() method.

    Jun 7, 2016 at 4:01

  • 1

    You cannot override the behavior of a java.lang.Thread by overriding the run() method. In that case you need to override the start() method I guess. Normally you just reuse the behavior of the java.lang.Thread by injecting your execution block in to the run() method.

    – sura2k

    Jul 6, 2016 at 9:28

  • The inheritance is not just for overriding some behavior, is also to use common behaviors. And it is the opposite, the more overrides, the worser hierarchy.

    – peja

    Aug 30, 2018 at 13:41