Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does Thread implement Runnable?

Tags:

java

runnable

A Java Thread's run() method is called by the JVM, on that thread, when the thread starts. To give a thread something to do, you can make a subclass of Thread and override its run() method, or (preferred) you can supply a Runnable to the thread's constructor. That's fine.

I was in the midst of making a subclass of Thread and overriding run, and I realized I couldn't make the method protected as I expected to because Thread.run() is public. Then I realized why: it has to be public because Thread implements Runnable. But why does it implement Runnable?

It doesn't seem logical. A thread is startable (from the current thread), but you don't run it in the same way you run() a Runnable (from the current thread); the thread runs itself (on its own thread). If you do call a Thread's run method manually, then you're not using it as a Thread, just a heavyweight Runnable.

Because of the design, any code with access to a Thread object can call its public run method and potentially poke into code that is not intended to be public or designed to be called that way. It also allows very peculiar things like this:

Thread.currentThread.run(); 

Is there a legitimate use for Thread implementing Runnable that I'm not seeing?

like image 316
Boann Avatar asked Aug 19 '13 03:08

Boann


People also ask

Does Thread implement runnable?

The Thread class itself implements Runnable with an empty implementation of run() method. For creating a new thread, create an instance of the class that implements Runnable interface and then pass that instance to Thread(Runnable target) constructor.

Why do we implement runnable in Java?

That is why we should implement Runnable interface to create a thread. Runnable makes the code more flexible as, if we are extending a thread, then our code will only be in a thread whereas, in case of runnable, one can pass it in various executor services, or pass it to the single-threaded environment.

Why is it better to implement runnable interface while creating threads?

When we extend Thread class, we can't extend any other class even we require and When we implement Runnable, we can save a space for our class to extend any other class in future or now. When we extend Thread class, each of our thread creates unique object and associate with it.

Why do we have runnable interface if everything is managed by Thread class?

"The Runnable interface should be implemented by any class whose instances are intended to be executed by a thread. [...] This interface is designed to provide a common protocol for objects that wish to execute code while they are active. For example, Runnable is implemented by class Thread."


2 Answers

The reason is "backwards compatibility".

The Thread class originated in Java 1.0 ... or earlier. In those days, Java didn't have inner classes, and so there wasn't a light-weight way to implement a Runnable instance. If you look at old threading examples and tutorials from that era, it is common to see classes that extend Thread and override the run() method.

Over time, it was realized that extending Thread is not a good idea (for various reasons). However, the Thread design could not be changed because that would have made old Java code incompatible with newer JVMs.


Is there a legitimate use for Thread implementing Runnable that I'm not seeing?

It depends what you mean by "legitimate".

  • Old code that was written in the early days is not "illegitimate" by virtue of doing things the old way. There is nothing "broken" about it.

  • There are potentially scenarios where it does make sense to extend Thread and override the run() method. For example, you might want run() to implement some special mechanism for passing info in or out of the supplied Runnable, or implement some special exception handling, or ... make the thread "restartable".

  • There might even be scenarios where you'd want to call run() directly on a thread object. For instance if you were handed some "dogs breakfast" code that extended Thread and you had to convert it to run in a thread pool without modifying the original code. You might consider instantiating the crufty thread class and passing the instances as runnables to the threadpool to run. (Yes ... horrible!)

like image 179
Stephen C Avatar answered Oct 05 '22 22:10

Stephen C


Overriding run doesn't explain why it ever needed to be public though.

If this is your issue, I think there's simple answer for that: methods implementing an interface must always be public in java. It would be possible with an abstract class for it to be protected, but if Thread were abstract, you wouldn't be able to use it as such.

As to why is Thread implementing Runnable in the first place, java must have a way of knowing at which part the thread is actually doing its job. They use run method for that. They could have more clearly separated the logic of just implementing Runnable and having Thread subclass implement that, but that is what I consider a minor mistake which is hard to change due to historical reasons.

TLDR; AFAIK there really isn't a good reason for a Thread to implement Runnable, but there is reasons for it to implement some kind of interface like that - they should've just probably had some kind of separated interface like ThreadRunnable instead of using the same Runnable interface that has other uses as well.

Note also that on modern java you should probably anyway use Callables and FutureTasks instead of Threads. "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.", quoting another answer here on stackoverflow.

like image 25
eis Avatar answered Oct 05 '22 22:10

eis