开发者

Why is the java.lang.Thread class in Java not marked final by the designers?

开发者 https://www.devze.com 2023-02-19 19:31 出处:网络
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 con

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.

0

精彩评论

暂无评论...
验证码 换一张
取 消