My question is that is there any reason for Thread class to implement Runnable interface by itself. Are there any specific use cases where overriding Thread makes more sense than implementing Runnable by design

  • 1
    This exact question has been asked on Stack Exchange: stackoverflow.com/questions/541487/… Jan 3, 2019 at 17:19
  • @BobDalgleish Thanks. I have already referred to the question before asking, that question compares the both approaches, but my question is specifically about when extending Thread makes sense
    – Bharat
    Jan 3, 2019 at 17:28

2 Answers 2


One of the examples mentioned on Javadoc's Thread page is the following:

 class PrimeThread extends Thread {
     long minPrime;
     PrimeThread(long minPrime) {
         this.minPrime = minPrime;

     public void run() {
         // compute primes larger than minPrime
          . . .


 PrimeThread p = new PrimeThread(143);

The intention is to be able to simply override Thread class and provide your own logic for the run method. While you can also directly pass a Runnable instance to Thread, this provides another means to be able to perform an asynchronous action requiring parameters to be provided.

Though I should probably mention that using Thread class in this way is deprecated. There are plenty of improved ways of launching threads in Java 8 and beyond. This article provides good reasons why you should probably prefer ExecutorService instead.

More recent examples include the use of streams, which is described in detail in this article, which generally are preferable even moreso than the ExecutorService if you don't need the fine-grain control over the threading.

Good luck!


It has already been clarified that there are two ways to define the logic to be executed when working with Thread.

Your question's title though contains more. Why does Thread implements Runnable (please let me amend that) if starting it always requires calling start() instead of Runnable's run()?

Technically it is indeed not required. The designers of that class could have decided to call the method of Thread you might override work instead of run and then start would call the injected Runnable#run() or Thread#work(). The common pattern of creating a Thread (either way) and calling start() on it would still work.

Now perhaps there are other reasons:

  • Consistency: don't invent new names for the same concept (still doesn't require to actually implement Runnable)
  • Reusability in other contexts: maybe they had in mind you would pass around a (not yet started) Thread object and let it execute by someone else. In case the strategy were to run the logic immediately instead of concurrently, that someone would need a method to call the actual synchronously runnable piece of code hidden inside the Thread (remember there are two ways to define it). To unify that, Runnable is appropriate (but offering an intermediate method public Runnable asSyncRunnable() would have worked too).

This site is temporarily in read-only mode and not accepting new answers.

Not the answer you're looking for? Browse other questions tagged .