questions on implementing Runnable [duplicate] - java

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java: “implements Runnable” vs. “extends Thread”
I have two questions about multithreaded programming. I read a few answers on the internet, but still I can't find a satisfying answer.
Implementing the Runnable is preferred over extending the thread class. Why?
How is it that we are able to get away with overriding just the run() method?
According to 'The Complete Reference to Java' by Herbert Schildt, If we are not overriding any methods of Thread class other than run(), it's better we implement Runnable.
My 2nd question might sound a bit silly, but I seem to be missing something and I'm not sure about how the whole thing works.

1: Implementing the Runnable is preferred over extending the thread class. why?
Because it allows your class to extend another class if it wants to instead of being forced to extend Thread.
2: How is it that we are able to get away with over-ridding just the run() method?
You can certainly override other methods but the Thread object will call the run() method when the thread is started. That's how it works. The default Thread.run() method is:
public void run() {
if (target != null) {
target.run();
}
}
If you call the Thread constructor with a Runnable then that is what the target is set to. If you instead extend Thread and #Override the run() method then that is the method that will be called when the thread object is started.
That's how the Thread class works.
2: How is it that we are able to get away with over-ridding just the run() method?
You may have misspoke here and were instead asking why we only need to implement the run() method in Runnable().
Runnable is an interface with a single run() method that you must implement.
Thread is a concrete class that you are extending. You can override any methods in a concrete class unless the class is final or the method is final.
Make sure you use proper Java terminology and don't mixup implement and override.

Three fundamentals before you delve deeper.
A class can only extend one class.
A class can implement any number of interfaces.
An interface can extend any number of interfaces.
Additionally, an abstract class is a class. So it behaves like a class and you can't implement it. You only extend it.

There are a number of traps which can occur if you extend Thread which you don't get with implementing Runnable.
public static String getName() {
return "My Test Application";
}
public static void stop() {
System.out.println("Shutting down");
}
public static void main(String... args) {
new Thread() {
#Override
public void run() {
System.out.println(getName());
stop();
}
}.run();
System.out.println("Bye now.");
}
prints
Thread-0
Bye now.
See how many bugs you can spot.

Unnecessary inheritance is generally a bad idea. You might hear "prefer composition over inheritance" often enough. I'm sure google can pull up enough links for you. The general issue is that inheritance bring tight, unnecessary coupling between classes.
Same goes for GUI components, btw.

Related

Why is Thread not an abstract class and start() not final?

Why was the Thread class implemented as a regular class and not an abstract class with run() method being abstract.
Will it possibly introduce any problems? Or does it have any use in being this way?
Also, the Thread.start() method is supposed to be a very specific method whose functionality cannot be implemented by any other class (If I am not wrong). And hence I guess the final keyword would be apt for this more than any other method.
But I am able to override this method and use it as I like,
public class Test extends Thread {
public static void main (String... args) {
Thread test = new Test();
test.start();
}
#Override
public void run() {
System.out.println("New thread started...");
}
#Override
public void start() {
System.out.println("Did anyone tell you I will spawn a new thread??");
}
}
It obviously only printed,
Did anyone tell you I will spawn a new thread??
Is there any use in overriding other than confusing the engineer replacing you?
If not, why was the method not declared final in Thread class?
You can of course choose to shoot yourself in the foot, but that doesn't mean you must.
Why was the Thread class implemented as a regular class and not an abstract class with run() method being abstract.
Because the recommended way to create a start a thread is not to subclass Thread. The recommended way is to define a Runnable, and pass it as argument to the Thread constructor:
Runnable r = new Runnable() {
#Override
public void run() {
...
}
};
Thread t = new Thread(r);
t.start();
And hence I guess the final keyword would be apt for this more than any other method.
Yes and no. You can't replace the implementation of start() by your own implementation, but you can do additional things in start() if you want:
#Override
public void start() {
System.out.println("Did anyone tell you I will spawn a new thread??");
super.start();
}
That said, if Java was redesigned from scratch today, there is a good chance the design would be different. Remember that this class dates from Java 1.0, and is still backward-compatible.
Why was the Thread class implemented as a regular class and not an
abstract class with run() method being abstract.
This question actually boils down to the fact that you should always prefer composition over inheritance.
If the Thread class was declared as abstract, the language would have to provide another class that extended from it which programmers could use to create a Thread. Your question would then be about why this class that extends from Thread is not abstract. If the language did not provide another class that extends from Thread, programmers would have to create their own class that extends from Thread and override the run() method.
If not, why was the method not declared final in Thread class??
The only possible explanation I can give is that the developers of the language saw some use-cases for overriding start when the class was introduced to the JDK. The first version of Java that I used was 1.5 and I personally have not come across a use-case where I found the need to override start. As JB Nizet stated in his answer
if Java was redesigned from scratch today, there is a good chance the design would be different
Why is Thread.start() not final?
Are you sure you would never want to override it?
Class MyThreadFactory implements ThreadFactory {
#Override
public Thread newThread(Runnable r) {
return new Thread(r) {
#Override
public void start() {
LOGGER.info("Starting thread " + this);
super.start();
}
};
}
}
I feel a few calirifcations should be posted for the answers :
"Are you sure you would never want to override it?"
No ! I would not. Thats like saying, "Are you sure , you want to declare this variable private?" Because if I could declare any variable I use as public without fearing that other developers may mess my design logic, coding would be a breeze. One of the most important purpose of OOPS concepts of Scope, abstraction, polymorphism, Error handling etc is to communicate to other developers the design and intentions behind your code.As pointed out in the question, when you override start method, nobody is forcing you to use super.start(). #Codebender wrote a start method for a thread without using super.start() and compiler never complained. So he is free to break the whole mechanism of Threading and compiler is suppose to just let it pass? Thread's start method ensures that run method is called and execute at the right time ! It is critical to the very concept of Threading. I would be more than happy to be corrected, if I missed something here.
2.
Because the recommended way to create a start a thread is not to
subclass Thread.
OK, if codebender is allowed by design, to sublass Thread and mess up the start method, By that logic, it is the design shooting itself in the foot.
By another statement made,(which I agree with completely) , Runnable is the recommended way. Then why do we allow Thread class at all to instantiate the thread at all with no restrictions? This is followed by :
You can't replace the implementation of start() by your own
implementation,
That actually supports codebender's claim that start method should be final when you say that.. ^
The one point, that's valid, is mentioned already as a side note, but is the actual answer to this question
"Backward compatibility".
In fact, improvements were even going on as late as JDK 5.0 , when they incorporated many major additions and clarifications to the Java concurrency model. We want backward compatibility to be supported all the way and thats why Thread class is still exactly as it was before, even though Runnable interface is the recommended way nowadays.
Again, I would be more than happy to be corrected, if I missed something.

Why does java.util.concurrent.RunnableFuture have a run() method?

As I was going through JDK 7, I found that java.util.concurrent.RunnableFuture<V> has a run method. I wonder what the significance of duplicating the same run method signature in the interface is when it already extends Runnable.
package java.util.concurrent;
public interface RunnableFuture<V> extends Runnable, Future<V> {
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
}
It's defined in the interface so that they can attach RunnableFuture-specific JavaDoc to it. There's no technical significance.
There are no docs that provide such explanation. So I am going to provide my opinion.
I dont think it has any major significance. Imagine how the interface world look
public interface RunnableFuture<V> extends Runnable, Future<V> {
}
Though it is perfectly valid it does not clearly indicate its purpose. So in my opinion it is just been provided for easy understanding for run() method specific to RunnableFuture interface. So that you know to put your runnable logic by overriding run() method.
Another point that I can think of is Runnable is one of the early interfaces and if you see the run() method it is
public abstract void run();
and public and abstract keywords are redundant as methods in an interface are by default public and abstract. To improvise this might be one of the reasons.

Use of creating a Thread by extending a Thread class [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Java: “implements Runnable” vs. “extends Thread”
Java provides two options to create a Thread class i.e either by implementing Runnable or by extending Thread class.
I know there can be many reasons to implement a Runnable but not sure where the scenario would be to extend a Thread class to create own Thread class?
Could you please provide me scenarios where extending Thread seems to be feasible or better option or advantageous...
There was a
Question on the threads but that did'nt answer my question
There is almost no reason to extend Thread, basically the only reason you would want to extend thread is if you were going to override things other than run() which is generally a bad idea. The reason it is less common to extend Thread is because then the class can't extend anything else, and if you're only overriding the run() method, then it would be kinda pointless to extend Thread and not implement Runnable.
Runnable is an interface with just one method run() that needs to be implemented by the class implementing the interface.
e.g.
public class MyRunnable implements Runnable {
#Override
public void run() {
//...
}
}
MyRunnable is not a Thread nor can you create a new thread just by using that class. So, it doesn't quite make sense to say -
Java provides two options to create a Thread class i.e either by implementing Runnable ...
You can extend the Thread class but just like #John said there isn't any point in doing so.
But if you want to execute some code in a new thread then the following is the best way -
MyRunnable r = new MyRunnable();
Thread t = new Thread(r);
t.start();
t.start() method starts a new thread and invokes run() method on r (which is an instance of MyRunnable.

How does this threadExample work?

I wanted to write multiple threads under one class and found one way of doing it.
public class ThreadExample {
public static void main(String[] arg)
{
Thread one = new Thread() {
public void run() {
try {
Thread.sleep(2000);
} catch(InterruptedException e) {
e.printStackTrace();
}
System.out.println("One");
}
};
Thread two = new Thread() {
public void run() {
System.out.println("Two");
}
};
one.start();
two.start();
}
}
Thing I don't get here is, I am neither extending the Thread class nor am I implementing the Runnable interface. How do I understand this?
And If the answer is, "I am just creating the object of the Thread class and using it, then why not always do this rather than doing the things mentioned above?
Technically, what you are doing is extending Thread. You are extending it on the fly with something called an anonymous inner class - to learn more about what that is, start here and read this page plus the next two.
What this means is you are creating temporary inline subclasses that have no name, and whose definitions survive only until the method finishes. Why do this rather than create a named subclass of Thread or implementation of Runnable? It makes sense when the body of run() is as simple as the examples above - there's less typing and fewer .java files to keep track of. One-off simple tasks like these are good candidates for anonymous inner class extension of Thread. For major program logic, you probably want to do a full named class implementation in a separate file.
In addition, once you've gotten good experience with Thread, I would encourage you to check out the java.util.concurrent package.
Ah, but you are extending the Thread class... anonymously.
When using the new Class() {} syntax, you are creating an anonymous class that is a sub-class (ie effectively extends) of the named class.
In this case, you have overridden the Thread.run() method.
This approach, while it works, it not considered "good design", because you are extending Thread, but you are not creating a new kind of Thread. It is better to pass a Runnable into the constructor:
new Thread( new Runnable() {
public void run() {
// do something
}
}).start();
Bohemian answered your first question so I'll answer your second one: "I am just creating the object of the Thread class and using it, then why not always do this rather than doing the things mentioned above?"
If you always do it the way you did in your question then you can't separate the logic that performs the task from the way the task is run. Implementing runnable lets you bundle the logic that performs your task separately from the code that manages how your task is run.
If you use runnables you are able to run your task in a new thread, run your task in the calling thread, run your task after some delay or run it in some other fashion without modifying the code in the runnable.
When working with threads you'll generally want to use an ExecutorService instead of using the thread class directly. Executor services provide facilities for limiting the numbers of threads, handling failed executions, determining when a runnable completes, getting return values from tasks run in other threads and so on.

Threads from a class with constructor with multiple arguments

Having a problem here, I have been learning about threading in java i understand if you are extending a thread you would create a thread in the main as follows.
Card thread1 = new Card("Ace");
This would be coming from a class called thread with a constructor
public thread(String n);
But i have given the constructor with a multiple argument:
public Person(int PersonID, Direction direction, StairLock stairLock)
And asked to create a thread for each of 4 people with two people going UP and 2 going DOWN and a lock for the stair, im unsure how to do this any help or direction would be helpful
There are multiple issues with your question.
Any class which extends thread, in its constructor, can call super(String) to pass the thread name to the superclass thread. So in your constructor for Person, you can call this constructor for Thread immediately with the name you want for the thread. It is a good practice to always name your threads for debugging identification.
You refer to the class thread, but you should know this is different from Thread. Classes in Java should always start with uppercase letters. If you made your own thread class, you are not actually making a thread.
I'm not sure why a Card or a Person class should need to extend Thread. Unless you're just picking random names for this example, these classes sound more like data objects rather than threads. If this is the case, you might want to consider having a separate class be the Thread which handles the movement up and down the stairs, and give each thread its own Person class instance to handle.
Given all of this, if you were asked to make a thread for each Person to handle its movement, I would recommend creating a separate class from Person to do this. Either extend Thread or implement Runnable and take a Person in the constructor. Both classes use a .run() method that you have to implement to do the workload of the thread. With a Thread, you can just instantiate it and call .start(). With a Runnable, you have to create a new Thread and pass the Runnable as an argument to the constructor, then call .start() on the Thread.
Many people prefer to use the Runnable approach, but the results are pretty much the same either way. If you're handling threads, you should be familiar with both ways of doing it.
Thread vs Runnable
You should probably not extend thread.
Implement Runnable and start a new thread with your Runnable.
Reason: If you extend Thread, you interfere with working infrastructure code. You should only do that if you need to change how things work. In 90% of cases, you only need to specify what needs to be executed, not how. That's why the Runnable approach is more elegant: you separate the what from the how.
From the Runnable docs:
In most cases, the Runnable interface
should be used if you are only
planning to override the run() method
and no other Thread methods. This is
important because classes should not
be subclassed unless the programmer
intends on modifying or enhancing the
fundamental behavior of the class.
Sample Code
Try something like this:
public void startThread(final int personID,
final Direction direction,
final StairLock stairLock){
new Thread(new Runnable(){
#Override
public void run(){
System.out.println("Person " + personID + " runs in direction "
+ direction
+ "and I have no idea what a Stairlock is, but here it is "
+ stairLock);
}
}).start();
}
OOP Design
In General, be careful how you model objects.
If I understand you right, Card is-a Thread in your concept. That's awful! A Card can have-a thread, but it should never be one!
In good OOP design, a class has exactly one purpose, this is called Cohesion. Also, different kinds of functionality should be loosely coupled, i.e. Domain Classes should never contain infrastructure code.
Firstly, welcome to the world of learning Threads. Sure, you can extend Thread, just call the constructors with right signatures. Or, you could implement the Runnable interface, too. The two implements below (A and B) are equivalent in terms of functionality. Now, Mr. Floyd told us not to extend Thread. Lets explore why (I do not disagree, just trying to help you understand a design issue in Java).
Class extension is Java's implementation of inheritance, a basic OO paradigm. When you extend Thread directly, you are saying "My class (Person) 'is a' Thread", and that is perfectly acceptable. The reason most people do not extend Thread in this manner is Java's lack of multiple inheritance. Now don't quote me on that, I have no statistics to back it up and it is also possible that their IDE's do not allow it or supervisors do not like it. But here is the issue:
Without debating whether multiple inheritance is good or bad, we can see that it is not there and safely assume that it aint gonna be there in the near future. This means that if your class extends Thread, it cannot extend anything else. This puts you in a bind. However, java allows your class to implement multiple interfaces, and Runnable can be just one of them. This gives you more degrees of freedom as the object designer, as you can pick from (extend) a variety of well established classes to suit your design goals and still have the multithreading functionality.
Hope that helps. Regards, - M.S.
// A
public class Person extends Thread {
public Person (int PersonID, Direction direction, StairLock stairLock) {
super();
// Other stuff for constructor
}
public void run () {
// Whatever you want to do with the thread
}
public static void main (String[] args) {
for (int i = 0 ; i < names.length ; i++) {
Person ace = new Person (names[i], xxx, xxx);
ace.start();
}
}
}
////////////////////////////////////////////////////////////
// B
public class Person implements Runnable {
public Person (int PersonID, Direction direction, StairLock stairLock) {
// Other stuff for constructor
}
public void run () {
// Whatever you want to do with the thread
}
public static void main (String[] args) {
for (int i = 0 ; i < names.length ; i++) {
Person ace = new Person (names[i], xxx, xxx);
new Thread (ace).start();
}
}
}

Categories