2

So, this question has been answered before (here and here), and the answers totally makes sense to me:

run() just calls the run() method of the Thread object, but without spawning a new thread. So, the code within the run() method actually is executed on the same thread it was called on. start() on the other hands over the the thread instance to the scheduler and calls run() there, so it spawns a new thread on which the code of the run() method gets executed.

However, I am struggling to really understand what the meaning of this is, so I developed a case to validate the statements:

public class Test extends Thread{

    public void run() {
        System.out.println("run() called on thread: " + getName());
    }

    public static void main(String[] args) throws Exception {
        System.out.println("main() called on thread: " + Thread.currentThread().getName());
        Test t = new Test();
        t.start(); // OR t.run();
    }
}

So, if the above was true, the output of the program should be that the name of the threads should be identical if I use t.run() to execute the print statement, since no new thread should be created and t is just running on the same thread that it was created on. On the other hand, t.start() should actually give me two different thread names.

However, in both cases I get the output:

main() called on thread: main
run() called on thread: Thread-0

Can anyone explain why calling t.run() also spawns a new thread and doesn't actually output:

main() called on thread: main
run() called on thread: main
Community
  • 1
  • 1
nburk
  • 20,293
  • 14
  • 73
  • 116
  • possible duplicate of [Java: What's the difference between Thread start() and Runnable run()](http://stackoverflow.com/questions/8579657/java-whats-the-difference-between-thread-start-and-runnable-run) – Hoopje Mar 24 '15 at 19:37
  • 1
    please read the question carefully! I refer to the possible duplicate, but I am extending it and request clarification on the specific situation! @Hoopje – nburk Mar 24 '15 at 19:38
  • You want `Thread.currentThread().getName()` - `run` is just a normal method, there's nothing that makes sure `this` is the current thread. – user253751 Sep 14 '15 at 13:50

3 Answers3

6

You are calling getName() on a Thread object, what do you expect? Of course you will get the name of that Thread object. Only that is not the thread you are currently operating in, for example:

Test t = new Test();
t.getName(); // What do you think you'll get?

I assume what you want to know will be answered by Thread.currentThread().name();

Let me rephrase that: You are not asking "Give me the name of the current thread in which this method is running" but "Give me the name of the thread object calling this method." - which is not the same.

Florian Schaetz
  • 9,670
  • 3
  • 27
  • 50
5

Calling getThread on your Test object returns the name assigned to that thread object, regardless of what thread is executing the run method of the Test object.

If you fix your code so that you're always getting the name of the current thread:

public class Test extends Thread{

    public void run() {
        System.out.println("run() called on thread: " + Thread.currentThread().getName());
    }

    public static void main(String[] args) throws Exception {
        System.out.println("main() called on thread: " + Thread.currentThread().getName());
        Test t = new Test();
        t.start(); // OR t.run();
    }
}

then you get results that show start uses a different thread:

main() called on thread: main
run() called on thread: Thread-5

and run uses the same thread:

main() called on thread: main
run() called on thread: main
Nathan Hughes
  • 85,411
  • 19
  • 161
  • 250
4

You are falling for a very common trap with the Thread API: the failure to distinguish a thread from an instance of the Thread class. These two are completely different concepts: a thread is not even an object, it is the system resource that does the execution of your code. A Thread, on the other hand, is just a plain Java object, which happens to have some magic methods, the most magical being start(). Many others are just plain old Java methods, and they pertain to that particular Thread instance.

getName() is just such a method and it returns the name of this instance on which it was called. currentThread(), on the other hand, is a static method which returns the instance of Thread responsible for the current thread. This is the instance on which you want to invoke getName().

Marko Topolnik
  • 179,046
  • 25
  • 276
  • 399
  • @sotirios Thanks for the links :) BTW the docs on `currentThread` just further the confusion! This is writing typical of the early days of Java. What's a "currently executing thread object"?? – Marko Topolnik Mar 24 '15 at 19:55