Sunday, 29 September 2013
Friday, 27 September 2013
Defining and Starting a Thread
An application that creates an instance of Thread must provide the code that will run in that thread. There are two ways to do this:
- Provide a Runnable object. The Runnable interface defines a single method, run,
meant to contain the code executed in the thread. The Runnableobject
is passed to the Thread constructor, as in the HelloRunnable example:
public class HelloRunnable implements Runnable {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new Thread(new HelloRunnable())).start();
}
}
- Subclass Thread. The Thread class
itself implements Runnable, though its run method does
nothing. An application can subclass Thread, providing its own
implementation of run, as in the HelloThread example:
public class HelloThread extends Thread {
public void run() {
System.out.println("Hello from a thread!");
}
public static void main(String args[]) {
(new HelloThread()).start();
}
}
Notice that both examples invoke Thread.start in order to start the new thread.
Differences between Thread and Runnable interface.
1) Java doesn't support
multiple inheritance, which means you can only extend one
class in Java so once you extended Thread
class you lost your chance and can not extend or inherit
another class in Java.
2) In Object
oriented programming extending a class
generally means adding new functionality,
modifying or improving behaviors. If we are not making any modification on
Thread than use Runnable interface instead.
3) Runnable interface represent a Task which can be executed by either
plain Thread or Executors or
any other means. so logical separation of
Task as Runnable than
Thread is good design decision.
4) Separating task
as Runnable means
we can reuse the task and also has liberty to execute it from different means.
since you can not restart a Thread once it completes. again Runnable
vs Thread for task, Runnable is
winner.
5) Java designer recognizes this and that's why Executors accept Runnable as Task
and they have worker thread which executes those task.
6)
Inheriting all Thread methods are additional overhead just for representing a Task which can can be done easily with
Runnable. Java doesn't support multiple inheritance
1) First reason is ambiguity around Diamond problem, consider a class A has foo() method and then B and C derived from A and has there own foo() implementation and now class D derive from B and C using multiple inheritance and if we refer just foo() compiler will not be able to decide which foo() it should invoke. This is also called Diamond problem because structure on this inheritance scenario is similar to 4 edge diamond, see below
A foo()
/ \
/ \
foo() B C foo()
\ /
\ /
D
foo()
In my opinion even if we remove the top head of diamond class A and allow multiple inheritances we will see this problem of ambiguity.
Some times if you give this reason to interviewer he asks if C++ can support multiple inheritance than why not Java. hmmmmm in that case I would try to explain him the second reason which I have given below that its not because of technical difficulty but more to maintainable and clearer design was driving factor though this can only be confirmed by any ofjava designer and we can just speculate. Wikipedia link has some good explanation on how different language address problem arises due to diamond problem while using multiple inheritances.
2) Second and more convincing reason to me is that multiple inheritances does complicate the design and creates problem during casting, constructor chaining etc and given that there are not many scenario on which you need multiple inheritance its wise decision to omit it for the sake of simplicity. Also java avoids this ambiguity by supporting singleinheritance with interfaces. Since interface only have method declaration and doesn't provide any implementation there will only be just one implementation of specific method hence there would not be any ambiguity.
Subscribe to:
Posts (Atom)