5

I was learning the concept of Multithreading in Java where I came across this very interesting behavior. I was experimenting with various ways of creating a thread. The one under question now is when we are extending a Thread, not implementing the Runnable interface.

On a side note, I am aware that it makes perfect OO sense to implement the Runnable interface rather than to extend the Thread class, but for the purposes of this question, let's say we extended the Thread class.

Let t be my instance of my extended Thread class and I have a block of code to be executed in the background that is written within my run() method of my Thread class.

It perfectly ran in the background with the t.start(), but I got a bit curious and called t.run() method. The piece of code executed in the main thread!

What does t.start() do that t.run() doesn't?

John Powell
  • 11,245
  • 6
  • 53
  • 64
avismara
  • 4,976
  • 2
  • 28
  • 53
  • 4
    I believe you can find your answers here: http://stackoverflow.com/questions/8579657/java-whats-the-difference-between-thread-start-and-runnable-run http://stackoverflow.com/questions/15841301/difference-between-running-and-starting-a-thread – Ognjen Babic Aug 29 '14 at 09:49
  • http://stackoverflow.com/a/13134221/3436942 tells you the difference in easy - enough language. Pretty much **t.start();** is making /creating a new thread whilst **t.run();** merely calls it on the main thread – jbutler483 Aug 29 '14 at 09:51

3 Answers3

8

That is what the class does. The t.start() will actually start a new thread and then calls run() in that thread. If you directly invoke run() you run it in your current thread.

public class Test implements Runnable() {
    public void run() { System.out.println("test"); }
}

...

public static void main(String...args) {
    // this runs in the current thread
    new Test().run();
    // this also runs in the current thread and is functionally the same as the above
    new Thread(new Test()).run();
    // this starts a new thread, then calls run() on your Test instance in that new thread
    new Thread(new Test()).start();
}

This is intended behavior.

nablex
  • 4,319
  • 4
  • 29
  • 48
1

The t.start() simply does what it says: starts a new thread, that executes the run()'s portion of code. t.run() is a function call on an object, from the current working thread (in your case, main thread).

Just keep in mind: only when call start() function of a thread, a new thread is started, otherwise, calling it's functions (other than start()) is the same as calling a plain function on any other different object.

artaxerxe
  • 5,760
  • 18
  • 61
  • 100
0

t.start() makes a native call to actually execute the run() method in a new thread. t.run() merely executes the run() in the current thread.

Now,

On a side note, I am aware that it makes perfect OO sense to implement the Runnable interface than to extend the Thread class

Actually, it makes perfect OO sense to follow either approaches (implementing Runnable or extending Thread). It is not that one is bad in OO sense. The advantage that you get by implementing Runnable is that you can make your class extend another class (which might actually break your OO design.)

TheLostMind
  • 34,842
  • 11
  • 64
  • 97
  • s/main thread/current thread/, AFAIK. – DarkDust Aug 29 '14 at 09:57
  • I was speaking with respect to current context. If you are planning to add features and functionalities to a `Thread`, then it makes sense to extend the `Thread` class. If you just want to create a new thread, implement the `Runnable` class. :) – avismara Aug 29 '14 at 09:58
  • @DarkDust - I am not getting you. – TheLostMind Aug 29 '14 at 09:58
  • 1
    Anyway, the main advantage of implementing Runnable is that in that case you are not extending Thread, therefore you don't inherit all the Thread class's baggage, which you could unintentionally involve (call/override/mutate) in your implementation code. – Marko Topolnik Aug 29 '14 at 10:08
  • 1
    It makes sense to extend Thread when you want to make a new _kind_ of Thread object. (If you wanted to override Thread.join() or Thread.setName() for example.) But, a Thread object is not a thread: It's an object that _manages_ a thread. Q: Does the object that manages a thread waiting for network clients have different responsibilities from the one that manages a thread running background tasks? Certainly the threads themselves have different responsibilites, but the Thread objects?... Not so much. – Solomon Slow Aug 29 '14 at 13:30