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
-
1This exact question has been asked on Stack Exchange: stackoverflow.com/questions/541487/…BobDalgleish– BobDalgleish2019年01月03日 17:19:00 +00:00Commented 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 senseBharat– Bharat2019年01月03日 17:28:09 +00:00Commented 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
. . .
}
}
Usage:
PrimeThread p = new PrimeThread(143);
p.start();
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 theThread
(remember there are two ways to define it). To unify that,Runnable
is appropriate (but offering an intermediate methodpublic Runnable asSyncRunnable()
would have worked too).