What is the essence of allowing the user to create thread by extending the Thread class when we can achieve the same fu开发者_高级运维nctionality by implementing Runnable and pass it to the Thread constructor.
achieve the same functionality by implementing Runnable and pass it to the Thread constructor
The use of extending Thread is not limited to Runnable. For example you can change the behavior of some methods or add your own thread local information (always accessible with Thread.currentThread()
).
From a historical perspective, you need to understand that the Thread
API was designed in Java 1.0, before Java supported anonymous inner classes. And a lot of the early example code shows subclassing of Thread
. It wasn't until later that:
- they added support for anonymous inner classes (Java 1.1)
- they figured out it was better to use inner classes (etc) to provide
Runnable
instances - they implemented standard classes for task execution, thread pools and so on (Java 5.0).
It is all very well saying "the Thread class in .Net is marked final", but you have to realize that C# / .Net came along a number of years later ... and was able to learn from the design of Java. Java was / is stuck with the historical baggage of a number of less-than-perfect design decisions ... because of an overriding imperative to NOT break old code.
Thread
is unusual in that it can take a reference to the Runnable
to run, but it itself is also Runnable
. By default, the Thread
will use itself as the Runnable
instance to run, though of course you can point it someplace else.
I think that that's no good reason to either mark Thread
final and require an external Runnable
or to make Thread
extendible and have it be its own Runnable
. Both approaches are perfectly fine and neither one seems like a much better choice than the other.
If I had to guess, the reason for making Thread
subclassable is that it allows you to write code like this:
Thread t = new Thread() {
public void run() {
/* ... your code here ... */
}
};
Which is marginally cleaner than creating a subclass of Runnable
and then wrapping it in a thread. Similarly, you can subclass off of Thread
to get a Runnable
that clearly indicates that it's supposed to be used as a thread. Of course, this is mostly a question of aesthetics, and had the Java designers gone the other way with this I think it would have been a perfectly fine decision.
If I acan add something, by extending Thread
you can have extended functionality of a thread (which is doesn't exist in Runnable
as it only contains the run()
method) like allowing your thread to act as a daemon thread (just like the Garbage Collector Daemon Thread). Other threads exists like the single non-daemon thread which calls the main method of a class (when the JVM starts up).
The Runnable
interface allows your class to become active as thread (by implementing a run()
method).
The thread class describes how the thread runs, the Runnable describes what is run. If you want to modify what is run, you should implement Runnable. If you want to modify how the thread is run you derive from Thread. In the case where you want to modify how a thread is run, you may derive from Thread and implement a separate Runnable object.
The only good thing I can think of is: if you extend the Thread class, It lets your run() method to be marked as protected. One disadvantage of implementing Runnable is that your run method MUST be marked as public.
精彩评论