Ok I'm looking at the API and I can create Thread like objects in two different ways.
The first being actually implementing the Thread class
class PrimeThread extends Thread { long minPrime; PrimeThread(long minPrime) { this.minPrime = minPrime; }
public void run() { // compute primes larger than minPrime . . . } }
Or, I can create a class that implements Runnable like this:
class PrimeRun implements Runnable { long minPrime; PrimeRun(long minPrime) { this.minPrime = minPrime; }
public void run() { // compute primes larger than minPrime . . . } }
Now, in writing this post I think I found my own answer. The reason that you can create it in two different ways is because of the difference between implementing something and extending something. Whereas if it "is a" thread you would extend it, but if it "is something else" then you can implement Runnable so that you get the benefits of the Thread class without the deadly diamond of death problem.
Can someone just let me know if I am right, thanks?
Teaching yourself anything is always the cheapest way, but it definitely takes a lot of time and effort.<br /> <br />Thank you javaranch <a href="http://"http://faq.javaranch.com/view?HowToAskQuestionsOnJavaRanch"" target="_blank" rel="nofollow">Learn How to Ask Your Question</a> and be nice
Jeroen T Wenting
Ranch Hand
Joined: Apr 21, 2006
Posts: 1847
posted
0
It's mostly a philosophical discussion rather than a practical one, though it is often not possible to extend thread because your class will already be extending something else.
In fact, Thread itself can be used for this because it implements Runnable so you're indirectly implementing Runnable no matter what (so why not do it directly).
42
Jeff Albertson
Ranch Hand
Joined: Sep 16, 2005
Posts: 1780
posted
0
I would go farther and claim that the definition of Thread as implementing Runnable was a design mistake. I've never seen an real-life example where extending Thread was preferrable to just implementing Runnable.
There is no emoticon for what I am feeling!
wise owen
Ranch Hand
Joined: Feb 02, 2006
Posts: 2023
posted
0
Implementing the Runnable Interface There are good reasons for choosing one of these options over the other. However, for most cases, including that of the Clock applet, if your class must subclass some other class (the most common example being Applet), you should use Runnable.
Jeff Albertson
Ranch Hand
Joined: Sep 16, 2005
Posts: 1780
posted
0
Originally posted by wise owen: Implementing the Runnable Interface There are good reasons for choosing one of these options over the other. However, for most cases, including that of the Clock applet, if your class must subclass some other class (the most common example being Applet), you should use Runnable.
Hmmm.. you seem to be quoting that linked reference. Can you give me an example where it's better to extend Thread than to directly implement Runnable? And their example of prefering to implement Runnable because Clock already extends Applet doesn't impress me either, because one could have just as easiely defined it as:
Having an applet subclass also implement Runnable is old-school, and this code probably predates Java 1.1, when nested classes were introduced.
Stan James
(instanceof Sidekick)
Ranch Hand
Joined: Jan 29, 2003
Posts: 8791
posted
0
Whereas if it "is a" thread you would extend it, but if it "is something else" then you can implement Runnable so that you get the benefits of the Thread class without the deadly diamond of death problem.
Yup, that's pretty good, and very neat how you saw it as you wrote the question. That happens a lot.
A good point in the answers above is we can't think of a reason to ever make a new class that "is a" thread. So in this case we'd skip right over extending Thread as an option. Also it's risky and almost never the best option to extend any concrete class. Yeah, Sun does it now and then in the library but just let that be a lesson to not take Sun's word for anything without thinking for yourself.
Java avoids the "diamond of death" problem by just not allowing multiple inheritance, so that's a little less to the point today. I'd focus on using the most abstract thing that will work at the moment. The Runnable interface is definitely more abstract than the Thread class. Using abstractions helps you avoid and defer decisions, a nifty part of decoupling in OO design. [ May 19, 2006: Message edited by: Stan James ]
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
Jeroen T Wenting
Ranch Hand
Joined: Apr 21, 2006
Posts: 1847
posted
0
There might on occasion be valid reasons to change the generic behaviour ot Thread, but such situations are well beyond the scope of a beginner's question and even most veterans will never encounter it (I've never seen it, only heard about it from others working on arcane things like specialist classloaders for embedded devices).
Nicholas Carrier
Ranch Hand
Joined: Apr 14, 2005
Posts: 78
posted
0
All of these answers work for me in their own way, and I'd like to thank everyone for the help. I am currently going to take my decision to the grave :-D If my class is a Thread, I will extend Thread, other wise I will just implement Runnable.
According to Cay S. Horstmann and Gary Cornell in Core Java 2: Volume II - Advanced Features...
...forming a subclass of the Thread class ... is no longer recommended. You should decouple the task that is to be run in parallel from the mechanism of running it.
"We're kind of on the level of crossword puzzle writers... And no one ever goes to them and gives them an award." ~Joe Strummer sscce.org
Guy Allard
Ranch Hand
Joined: Nov 24, 2000
Posts: 776
posted
0
Originally posted by Stan James: ... Java avoids the "diamond of death" problem by just not allowing multiple inheritance ...
Just curious. Is there *any* statically typed language other than C++ that *does* deal with the diamond?
Thanks, Guy
Andrew Trumper
Greenhorn
Joined: Sep 08, 2001
Posts: 12
posted
0
Originally posted by Nicholas Carrier: Ok I'm looking at the API and I can create Thread like objects in two diff Now, in writing this post I think I found my own answer. The reason that you can create it in two different ways is because of the difference between implementing something and extending something. Whereas if it "is a" thread you would extend it, but if it "is something else" then you can implement Runnable so that you get the benefits of the Thread class without the deadly diamond of death problem.
Can someone just let me know if I am right, thanks?
Yes and no. "Deadly diamond of death"? Not sure what that is but I want one...
Implementing runnable and passing it to a thread object is and example of extendability using composition which can be thought of as a has-a relationship (Thread has a runnable).
Extending thread is an example of extendability through inheritance which can be thought of as an is-a relationship.
NOTE: Please don't think of inheritance and composition purely in terms of has-a and is-a. This is an over-simplification.
Runnable and Thread both exists because Runnable is independently usefll of Thread. A good example of this is Swing.invokeLater(). Thread pools also juggle Runnables and some state machines can be implemented with runnables too..
As for Thread allowing extendability through inheritance and composition.. I'm not sure why they did this. The general rule is if extensibility can be done using composition instead of inheritance without major drawbacks then do it using composition. I'm guessing they allow for both because it was very easy to implement. I think someone might have liked the idea that you can have code "belong" extend a Thread even though this has led to countless people thinking that only code in a Thread object can be run as a Thread.
Which method should you use? *sigh*. When dealing with threads there are more important things to worry about. To be honest I don't use either myself since I only use threads indirectly through a large concurrency library I wrote.
Originally posted by Nicholas Carrier: Ok I'm looking at the API and I can create Thread like objects in two different ways.
The first being actually implementing the Thread class
Now, in writing this post I think I found my own answer. The reason that you can create it in two different ways is because of the difference between implementing something and extending something. Whereas if it "is a" thread you would extend it, but if it "is something else" then you can implement Runnable so that you get the benefits of the Thread class without the deadly diamond of death problem.
Can someone just let me know if I am right, thanks?
You are right.
Clifton Craig
Ranch Hand
Joined: May 26, 2006
Posts: 103
posted
0
Real quick reply as I haven't read this thread in entirety. You only need to implement the Runnable interface in most (if not all) cases. You use the Thread class directly to start a new thread in the VM. I see no benefit to extending Thread outside of being able to invoke start() on your subclass. That in itself is no benefit considering you can instantiate a new thread giving it a runnable in the contructor and call start all inline. There are certain edge cases where you'll want to define additional functionality for a Thread, maybe your creating an external event dispatch queue polling object and it has some crazy feature where extending makes sense. I dunno. But almost always you can get away more cleanly with defining a Runnable and instantiating a Thread that uses it.
Holla at me...<br /><a href="http://codeforfun.wordpress.com" target="_blank" rel="nofollow">http://codeforfun.wordpress.com</a>