views:

83

answers:

4

Does anyone have any insight into the history of Java Thread class's run() method being public? Almost all the time, it gets used by overriding and thus would the protected modifier have been more appropriate? That would still leave the start() as the public api for users and thus not leave any room for mistakes with users calling run() accidentally.

+9  A: 

Thread implements Runnable, which defines the run() method, so it has to be public.

But since Java 1.5 is advisable to use the Executors services instead of java.lang.Thread. Executors are decoupling the unit of work to be executed (Runnable, Callable) from the actual executor. (With Thread they were the same thing)

Bozho
Yeah, you are right and I would think that's why the run() is in there as a public method. In fact, since there's a constructor that takes a Runnable argument - public Thread(Runnable target), that should have negated the need for implementing Runnable?
gshx
it "is NOT advisable"? not the contrary? :-)
Carlos Heuberger
thanks. an extra 'not' :) removed.
Bozho
@gshx - no, because a `Thread` is also runnable - i.e. an object that can be run in a new thread :)
Bozho
@Bozho, can you please elaborate on that or is it just a play on words :) If you look at the default constructor of Thread and the Thread(String name) constructor, they both call init() with a null Runnable target. So, it would be no use really to call a Thread a Runnable without injecting a Runnable target in it.
gshx
You can make a `Thread` by simply overriding the `run` method (as you said), and it is eligible for passing to any method that accepts objects to be executed in a new thread- so no passing of `Runnable` here, but still your object is runnable.
Bozho
Yeah, that would work but again by making this dummy Thread a Runnable target for some other Thread but not very useful imho. Having extended Thread will have constrained this dummy Thread class from extending a more useful parent if one was ever needed. It does seem to me that it would have been cleaner if Thread had not implemented Runnable in the first place and thus completely left out the public run() method on its api.
gshx
That is what the executors address - they are just executors, and not runnable objects. Thread is both.
Bozho
+2  A: 

run is defined in the Runnable interface and all methods defined in an interface are public.

willcodejavaforfood
Thanks but I should have elaborated some more in my question - does Thread really need to implement Runnable when it does all its work on the injected Runnable target inside it?
gshx
+2  A: 

You are better off not overriding Thread, you should create a Runnable and pass it into the constructor for the new Thread. That way the work being done, the Runnable, is kept separate from the implementation mechanism, the Thread.

Nathan Hughes
Nathan, I agree with you and that's why I am wondering why is it there in the first place - what is the use of Thread implementing Runnable when the Thread class already has a constructor that accepts a Runnable which overrides run()
gshx
@gshx: Good question, my guess is it is provided as a shortcut.
Nathan Hughes
A: 

I think it's basically a bad design that, in the interest of making things "simple" for the user, allowed coupling the task to be run (the Runnable) to the thread to run it on directly. Since Thread was added in JDK 1.0, though, that design hasn't been able to be changed since then, just deprecated (sort of) in favor of the Executor framework. JDK 1.0 was a long time ago, and various mistakes were made without the benefit of experience since then.

ColinD
I am actually in favor of deprecating the run() on Thread with a suggestion to use executors instead. It is clearly impossible to make it protected now.
gshx