Implementing Runnable vs. extending Thread [duplic

2020-02-04 20:02发布

Why is implementing Runnable a better option than extending from Thread class?

标签: java
6条回答
放荡不羁爱自由
2楼-- · 2020-02-04 20:22

It might not make any sense in your inheritance hierarchies to extend Thread. Only extend Thread if you wish to modify the functionality of Threads.

With Runnable, any class in any inheritance hierarchy can expose a task that can be seen as a unit of work to have a Thread perform.

查看更多
够拽才男人
3楼-- · 2020-02-04 20:29

Because IS-A really isn't what you want. Your class wants to be Runnable, but IS-A Thread feels too strong. That's what inheritance is saying. You really just want to implement the run() method, not all the other attendent stuff in the Thread class.

This falls in line with Scott Meyers very good advice in "More Effective C++": Make non-leaf classes abstract. Substitute interfaces and you're spot on.

查看更多
ゆ 、 Hurt°
4楼-- · 2020-02-04 20:32

To answer the question first:

If you extend thread, an instance of your class (extended thread) will always call the constructor of the superclass thread. So MyClass myclass = new MyClass() will always calls "super()" inside the constructor of MyClass which instantiates a thread, and in the end you may implement some overhead into your class (if you don't use any method of the superclass thread). So implementing only Runnable allows your class running faster without any inherited overhead.

Further, there are some wrong answers here:

Now I extend just the few things that clearly and obviously pass the "is-a" test and everything else is an interface...

Didn't you ever consider to create an object without any interface? Because it would be very wrong to implement an interface for every object!

When you extends Thread class, each of your thread creates unique object and associate with it. When you implements Runnable, it shares the same object to multiple threads.

Wrong, everytime you call the constructor of a class, you will get an own object, it doesn't matter from where it is extended or what it implements!

Conclusion: In java, EVERY class instance is an object, and extends the class Object (while primitives aren't...only array of primitives like int[] classes extends Object, and such arrays have the same methods like any object - but sadely they're not mentioned in the Javadoc! The Sun guys probably didn't want us to use them).

Btw there are at least two advantages of inheritance: Code sharing and a clear Javadoc. Because if you inherite from a class, you can see all subclasses in the Javadoc. You could do that with an interface too, but then you can't share code. Even more, then you would need to create "nested" objects and call the constructor of two or more objects instead of only one, and this again would mean you implement some overhead from the superclass Object itself! Because there is no object in Java without overhead, and creating as less objects as possible is quite important for high performance applications. Objects are the greatest thing, but unnecessairy objects aren't...

查看更多
甜甜的少女心
5楼-- · 2020-02-04 20:34

This way you decouple the computation (the what) from the execution (the when and/or the how).

With Runnable or Callable, you can for instance submit many work/computation to an Executor which will take care to schedule the stuffs. Here is an excerpt form ExecutorService:

pool = Executors.newFixedThreadPool(poolSize);
...
pool.execute(new Handler(serverSocket.accept()));
...
class Handler implements Runnable {
    ...
 }

Using Runnable/Callable gives you more flexibility that using Threads directly.

查看更多
Emotional °昔
6楼-- · 2020-02-04 20:35

The actual point to take away is that implements is ALWAYS preferred over extends on any questionable cases.

Extends binds two class files very closely and can cause some pretty hard to deal with code.

When I first "understood" OO programming I was extending EVERYTHING, but it turned my whole design into mush. Now I extend just the few things that clearly and obviously pass the "is-a" test and everything else is an interface...

Many many problems just stopped happening (Confusing multiple inheritance situations, time wasted refactoring hierarchies, the tendency to have "protected" variables then wonder why they are changing when you didn't change them in the current class, chaining requirements for constructors, figuring out how different inheritance-trees interact with each other, ...

It seems like every 3 years (for the last 20) I think I really "Get" programming and look back at the stupid things I did 3 years ago in shame... This was one of those instances (but from closer to 7 years ago at this point)

查看更多
疯言疯语
7楼-- · 2020-02-04 20:46

The reasons why you might prefer implementing the Interface Runnable to extending the Class Thread are the following:

  • less overhead in a sequencial context (source)

When you extends Thread class, each of your thread creates unique object and associate with it. When you implements Runnable, it shares the same object to multiple threads.

Source: a blog - I'm not quite sure if that's correct

  • you can send tasks over the network with Runnable (Thread is not serializable, source)
  • better OOP-style
    • it's very likely that you don't have a "is a" relationship
    • you have the possibility to extend other classes (Java has no multiple inheritance)
查看更多
登录 后发表回答