This week's book giveaway is in the OCAJP 8 forum. We're giving away four copies of OCA Java SE 8 Programmer I Study Guide and have Edward Finegan & Robert Liguori on-line! See this thread for details.
I leant from Bruce Eckel's Thinking in Java 3rd Edition that generally speaking, extending Thread is a more OOP manner than implementing Runnable:
The only thing required by a Runnable class is a run( ) method, but if you want to do anything else to the Thread object (such as getName( ) in toString( )) you must explicitly get a reference to it by calling Thread.currentThread( ). This particular Thread constructor takes a Runnable and a name for the thread.
When something has a Runnable interface, it simply means that it has a run( ) method, but there�s nothing special about that�it doesn�t produce any innate threading abilities, like those of a class inherited from Thread. So to produce a thread from a Runnable object, you must create a separate Thread object as shown in this example, handing the Runnable object to the special Thread constructor. You can then call start( ) for that thread, which performs the usual initialization and then calls run( ). The convenient aspect about the Runnable interface is that everything belongs to the same class; that is, Runnable allows a mixin in combination with a base class and other interfaces. If you need to access something, you simply do it without going through a separate object. However, inner classes have this same easy access to all the parts of an outer class, so member access is not a compelling reason to use Runnable as a mixin rather than an inner subclass of Thread.
When you use Runnable, you�re generally saying that you want to create a process in a piece of code�implemented in the run( ) method�rather than an object representing that process. This is a matter of some debate, depending on whether you feel that it makes more sense to represent a thread as an object or as a completely different entity, a process. If you choose to think of it as a process, then you are freed from the object-oriented imperative that �everything is an object.� This also means that there�s no reason to make your whole class Runnable if you only want to start a process to drive some part of your program. Because of this, it often makes more sense to hide your threading code inside your class by using an inner class, as shown here:
InnerThread1 creates a named inner class that extends Thread, and makes an instance of this inner class inside the constructor. This makes sense if the inner class has special capabilities (new methods) that you need to access in other methods. However, most of the time the reason for creating a thread is only to use the Thread capabilities, so it�s not necessary to create a named inner class. InnerThread2 shows the alternative: An anonymous inner subclass of Thread is created inside the constructor and is upcast to a Thread reference t. If other methods of the class need to access t, they can do so through the Thread interface, and they don�t need to know the exact type of the object.
The third and fourth classes in the example repeat the first two classes, but they use the Runnable interface rather than the Thread class. This is just to show that Runnable doesn�t buy you anything more in this situation, but is in fact slightly more complicated to code (and to read the code). As a result, my inclination is to use Thread unless I�m somehow compelled to use Runnable.
The ThreadMethod class shows the creation of a thread inside a method. You call the method when you�re ready to run the thread, and the method returns after the thread begins. If the thread is only performing an auxiliary operation rather than being fundamental to the class, this is probably a more useful/appropriate approach than starting a thread inside the constructor of the class.
But, in the book for SCJP exam by Kathy and Bert says:
...You need to know about both for the exam, although in the real world you�re much more likely to implement Runnable than extend Thread. Extending the Thread class is the easiest, but it�s usually not a good OO practice. Why? Because subclassing should be reserved for classes that extend an existing class, because they�re a more specialized version of the more general superclass. So the only time it really makes sense (from an OO perspective) to extend Thread is when you have a more specialized version of a Thread class. In other words, because you have more specialized thread-specific behavior. Chances are, though, that the thread work you want is really just a job to be done by a thread. In that case, you should design a class that implements the Runnable interface, which also leaves your class free to extend from some other class...
I was confused, which approach is generally better on earth? Personally I found Bruce Eckel's statements more convincing. I have read all the 4 threads discussing the " Thread vs Runnable " in this board, but the confusion is still there. I guess in practical work it's not a big deal one extends Thread or implements Runnable ( Thread also implements Runnable ), sometimes just depends on programmer's personal preference. But now I need to make my concept clear -- going to do an exam focusing on threads and also SCJP exam very soon. It would be great help if somebody could kindly clarify the two approachs to me, thank you very much in advance. Regards, Ellen P.S.: Suppose, I were given some system requirment/specification to implement something( threads heavily involved ), and then were asked: Thread or Runnable, your choice? and why? I am submitting this post in order to make the thinking of such question clearer. Thanks again. [ February 11, 2003: Message edited by: Ellen Zhao ]
First and most importantly - what happened to Ellen Fu? Where is she, and what have you done to her? As for your original question - ummm, for me it sorta depends on my mood. I tend to decide this much like I decide whether to use an anonymous class, or create a separate top-level named class (or something in between). That is, if a given task or class is pretty short and simple, then I'll tend to define and use it in the simplest manner possible - which is usually to extend Thread / use an anonymous class. (In fact these two distinct examples may well overlap if I find myself creating an anonoymous class which extends Thread.) But if the task or class is a bit more compex, I will be more likely to break it off into a separate top-level class - which in the Thread vs. Runnable case means I'll implement Runnable so as to isolate the code for "what the thread will do" from the methods that control starting, interrupting, etc. It's just a choice of how much complexity to put in a single class, so as to avoid confusing the reader unnecessarily. Of course, in the event you want your class to extend some other class (other than Thread) then you kind of have to implement Runnable, since you can't extend two different classes. Other than this situation, I don't think it really matters much which method you use. Both forms are fairly common in the industry, and people will give you advice based on what they're more used to. It's generally pretty trivial to refactor one form into the other if you need to later, so I wouldn't worry too much about making the wrong choice initially. For the SCJP exam, you almost certainly will not need to decide for yourself which form to use. But you will need to be able to interpret code written in either idiom, and figure out what the results will be. You may find it a useful excercise to take code written in one idiom and rewrite it to use the other instead - just to give you a better sense of the differences. [ February 10, 2003: Message edited by: Jim Yingst ]
"I'm not back." - Bill Harding, Twister
Joined: Sep 17, 2002
Hi Mr Yingst, Thank you very much for the explanation. It helps. As to your question, in fact the references Ellen Fu and Ellen Zhao in JavaRanch point to the same object -- me. Fu is the last name of my favourate character in a pc game which I played a lot when I was 15 years old. ( it's the first character on the linked page, he's a smart boy, the world in the game is more than 2000 years ago, China. Fu was pretty good at designing powerful robots at that time ) The reason I didn't choose "Zhao" as my display name when I just came to JavaRanch was that I thought it might look strange and awkward to pronunce to westerners. Later I knew JavaRanch better, JR's so friendly and open a place that I needn't worry about my last name at all. But I was sorta lazy to change my display name, it's only a symbol, no big deal. Days ago I got this Ellen Fu by a wild search with google ( was trying to dig out some usful information in my old posts.) -- OOps, the madam uses this name for her significant business, it seems that she has quite a few customers in California. I am only a student it doesn't matter if I asked any stupid questions ( such as: why are cs books soooooooo expensive? ) or sometimes I said any non-sense here, but what if her friends or potential customers saw my posts? They might think how kiddish she is or might even laught at her. It's not good for her. Time to differ myself from the madam...That's it. Ellen N. Zhao is my real name. Thank you for asking about it.
Best Regards, Ellen p.s.: Honestly I have no idea about most content on the madam's homepage, it's so much business-like, doesn't seem very appealing to me( at least for now ). That's another reason I was eager to claim "this ellen fu" is not "that ellen fu" when I saw her site. [ February 13, 2003: Message edited by: Ellen Zhao ]
Hello everyone, I actually had the same question, but one area which has not been mentioned is access to private members. According to O'Reilly's 'Exploring Java', implementing runnable (as opposed to extending Thread) "has the added advantage of allowing run() to access any private variables and methods it might need in the class." This leads me to believe that extending Thread does not give this option. If this is the case, then there is a significant difference. I suppose getter/setter methods could be used to overcome this.
Ellen, Don't worry about the name. I do know how to pronounce it but that's because I took Zhong1 Wen2, ye3 qu4 guo4 Zhong1 guo2 le. Personally, I think the pin yin format, while better than the old wade-giles transliteration is stupid. It's pronounced (approximately) Jao, so where the heck did the Z come from? Wade-Giles was even worse, you know the word for people/person, ren2? Well, in wade-giles it's jen. Now how do you get from the sound ren (where the r is sort of a cross between an r and an l) to a j? Anyways, what do you mean "westerners?" I've never been comfortable with terms like that. First the world is a sphere , and it's floating in space which as far as we know is "endless." So there is no up, down, left or right. (And if you ask Zhuang1 Zi3, there's no right or wrong either ). Of course, people are always "correcting" me because I refuse to use those terms. I'll (randomly alternating my response) say something like, "I'm going down/over to boston from new york," and inevitably someone will respond, "you mean up." Nope, there is no up or down! "Boston is UP from New York." Uh, relative to what? A point on a sphere? The "bottom" of the universe? Nice try. Sorry for the random thoughts, just needed a break from this dumb project I'm working on. [ February 21, 2003: Message edited by: Robert Paris ]
Joined: Sep 17, 2002
Originally posted by merlin bar: Hello everyone, I actually had the same question, but one area which has not been mentioned is access to private members. According to O'Reilly's 'Exploring Java', implementing runnable (as opposed to extending Thread) "has the added advantage of allowing run() to access any private variables and methods it might need in the class." This leads me to believe that extending Thread does not give this option. If this is the case, then there is a significant difference. I suppose getter/setter methods could be used to overcome this.
Thank Merlin, good information!
Robert, I thought you were going to tell me some truth of java concurrency in this thread and read on with a thrilling expectation but soon caught an InterruptedException Just kidding
Sorry for the random thoughts, just needed a break from this dumb project I'm working on.
No need to feel sorry, you are very welcome to start some comparative-culture-talk thread and your this post has already amazed me: you speak cool Chinese indeed, the accurate 4 tones even cooler than some native Chinese people.No exaggeration here. It's definitely not easy for a foreigner. And even...Zhuang1 Zi3...wow, my admirations!! It's my pleasure to discuss these stuff with you and answer the questions you raised, however, I'm going to do it in the Meaningless Drivel board. This is a threads & synchronisation board, I don't feel too comfortable to lessen too much sense of profession here. Sorry. In addition, Mr. Merlin Bar put his very first post in JavaRanch in my thread, how would he think when see people are distracting the topic under his post right away? Let's be a bit formal to new comers, how do you think? Okay, now I'm doing my finals cannot think too much other than threads, next Wednesday I'll post sth. like "Mr. Robert Paris please come in" in the Meaningless Drivel board. See you then. Regards, Ellen [ February 22, 2003: Message edited by: Ellen Zhao ]
Hi Ellen, it is interesting to notice that a Thread is also a Runnable, that is: it implements Runnable. So by extending Thread you are also implementing Runnable. So is there really any real difference in the two approaches? So far, however, I have never had to model any Threads, only processes that have to be multithreaded. So I go for implementing Runnable and kicking off a Thread that runs the Runnable. That puts me in the Sierra/Bates camp I guess. Cheers - Barry
Its a matter of taste. Thread has a lot of other methods on it for free, such as name and I think printing stack traces, but most of those are static anyway. the GOF suggest that implementing is to be preferred over extending to be more in OO style. So I am baffled that someone suggested that extending Thread is more OO.
Joined: Jan 30, 2000
According to O'Reilly's 'Exploring Java', implementing runnable (as opposed to extending Thread) "has the added advantage of allowing run() to access any private variables and methods it might need in the class." This leads me to believe that extending Thread does not give this option. If this is the case, then there is a significant difference. I can't see any reason this would be true. The only major thing you can do with Runnable that you can't do with Thread, is that you can extend another class while also implementing Runnable. But I don't see how that's relevant here. If you want to access private members of a class in another thread, there are several options:
Have that class implement Runnable, or extend Thread (if it doesn't already extend something else. This probably isn't a good OO solution - if the class wasn't already a Thread or Runnable when you first conceived of it, it probably exists for some other purpose - and making it Runnable now will just confuse us.
Declare an inner class inside the other class, which either extends Thread or implements Runnable. Inner classes normally have access to all data from the enclosing class, even the private data. This is often the most elegant solution.
Modify the class to include get/set methods, so the private data is more accessible. You have to decide how much access is appropriate. Perhaps the get/set should be package level or protected, rather than public.
Use reflection to access private data. Seldom a good idea, but if you're desperate...