When would you call java's thread.run() instead of thread.start()?
Asked Answered
S

14

111

When would you call Java's thread.run() instead of thread.start()?

Sect answered 4/11, 2008 at 18:21 Comment(4)
When I'm the thread.start() method? :)Pucka
@blank, The answer is simply: t.run() when you want to run t's task on the current thread, and t.start() when you want to run t's task on thread t itself. Or are you asking for actual use cases?Feral
When you are an idiot and want to spend an hour debugging multithreaded code just to realise later that you should just have called start() ! Like me... This method should jut not be public!Siddur
See also #2674674Nahuatl
F
115

You might want to call run() in a particular unit test that is concerned strictly with functionality and not with concurrency.

Fang answered 4/11, 2008 at 18:26 Comment(0)
C
95

Never. Calling run() directly just executes the code synchronously (in the same thread), just like a normal method call.

Comply answered 4/11, 2008 at 18:23 Comment(8)
"Never" is a bit too absolute. Maybe don't always want a new thread, and still execute the code?Malmo
Maybe, but in that case it would be needlessly wasteful to create a new Thread only to call run() method. Better to create a Runnable impl and either run that in-thread or construct and start a new Thread with it.Elisabeth
Absolutes usually are too strong, but then again, rules are made to be broken. I think keeping it clear and simple is best, especially for beginner programmers. Besides, this case is one that's pretty cut-and-dry. Scott Bale nailed it when he suggested using Runnable.Comply
Just revisiting ... if never, why is the method public?Sect
It's public because Thread implements Runnable. You can subclass Thread and override run(), which has the same effect as putting your code in a Runnable and passing that into the Thread constructor. It's better practice to use a separate Runnable object, though, since that leaves you more flexibility (such as passing it to an Executor, etc.).Comply
Let me give a concrete example I'm currently working with: I have a program that can either be run as a GUI or from the command line. In the GUI case, I want the object that does the heavy lifting to run on a separate thread and send updates to the gui. In the command line mode, I don't need that separate thread.Issi
To expand, the current code (not written by me) creates the thread, calls thread.start() and immediately calls thread.join(). It would make more sense to call thread.run() and be done with it. (Of course, it would make even more sense not to create the Thread at all, and just call the Runnable object's run() directly.)Issi
Supporting legacy or third party code does loosen the rules, but you still have to be careful. Calling start() then join() is not quite the same as just calling run(). ThreadLocals and locks will behave differently, as will other subtleties such as Thread.setContextClassLoader(). If a separate thread is not needed, it would still be better in the long run to rewrite the code (if it's legacy) to create a Runnable and either run that directly or start a thread with it.Comply
M
27

Taken form the Code Style Java threads FAQ:

Q: What's the difference between a thread's start() and run() methods?

A: The separate start() and run() methods in the Thread class provide two ways to create threaded programs. The start() method starts the execution of the new thread and calls the run() method. The start() method returns immediately and the new thread normally continues until the run() method returns.

The Thread class' run() method does nothing, so sub-classes should override the method with code to execute in the second thread. If a Thread is instantiated with a Runnable argument, the thread's run() method executes the run() method of the Runnable object in the new thread instead.

Depending on the nature of your threaded program, calling the Thread run() method directly can give the same output as calling via the start() method, but in the latter case the code is actually executed in a new thread.

Malmo answered 4/11, 2008 at 18:24 Comment(2)
thread's run() method executes the run() method of the Runnable object in the new thread instead. That isn't true (or at least my Java 8 source code tells otherwise), but unfortunately the link seems broken so i report the mistake here instead.Robot
@Tomalak, This doesn't answer the question asked. The question is not asking for the difference, but asking about use cases whereby we will call thread.run() instead of thread.start().Feral
T
25

Executing thread.run() doesn't create a new Thread in which your code gets executed. It just executes the code in the current Thread from which the thread.run() code is invoked.

Executing thread.start() creates a new OS level thread wherein the run() method gets called.

In essence:

Single Threaded programming → Directly calling the run() method

Multi Threaded programming → Calling the start() method

Moreover, as other's have mentioned, 'testing' seems to be the only advisable case wherein you may invoke run() directly from your code.

Trichology answered 21/5, 2012 at 5:38 Comment(0)
E
13

This has already been alluded to, but just to be clear: creating a new Thread object only to call it's run() method is needlessly expensive and should be a major red flag. It would be a much better, more decoupled design to create a Runnable impl and either (a) call it's run() method directly if that's the desired behavior, or (b) construct a new Thread with that Runnable and start the Thread.

Better yet, for even more decoupling, check out the Executor interface and framework in JDK 5 and newer. This allows you, in a nutshell, to decouple task execution (the Runnable instance) from how it is executed (the Executor implementation, which might execute the Runnable in the current Thread, in a new Thread, using an existing Thread from a pool, and whatnot).

Elisabeth answered 4/11, 2008 at 19:10 Comment(0)
A
9

Call thread.start(), it will in turn call thread.run(). Can't think of a case when you would want to bypass thread.start() and go directly to thread.run()

Anhanhalt answered 4/11, 2008 at 18:23 Comment(1)
During testing is the only legitimate case I can think of. Otherwise, the contents of run() should be in a separate method that gets called by run, or by other means.Pucka
C
9

The separate start() and run() methods in the Thread class provide two ways to create threaded programs. The start() method starts the execution of the new thread and calls the run() method. The start() method returns immediately and the new thread normally continues until the run() method returns.

The Thread class’ run() method does nothing, so sub-classes should override the method with code to execute in the second thread. If a Thread is instantiated with a Runnable argument, the thread’s run() method executes the run() method of the Runnable object in the new thread instead.

Depending on the nature of your threaded program, calling the Thread run() method directly can give the same output as calling via the start() method, but in the latter case the code is actually executed in a new thread.

reference

Clump answered 25/8, 2011 at 8:46 Comment(2)
Same as Tomalak answer!!If you have referenced from some place please mention that !!Knuth
The start() method returns immediately and the new thread normally continues until the run() method returns. If start() returns immediately how come the run() continues to run given that it was called itself from start()Superheterodyne
M
7

If the Question was - "why the thread start method is called instead of run method directly" then i have answered with an example code below. Hope that clarifies. In the Example below:

/*
By calling t1.start(), 
we are getting the main calling thread returned immediately 
after the t1.start() called and is ready to proceed for other 
operations.And the thread t1 starts executing the run method of the object r. 
Hence the the output will be:

      I am the main thread , i created thread t1 and had it execute run method, which is currently looping from 0 to 1000000

      I am done executing run method of testThread

*/


/* If we call t1.run() instead of t1.start(), (just replace t1.start() with t1.run() in the code for testing)
 its like a regular method call and the main thread will not return until the run method completes, 
 hence the output will be:

         I am done executing run method of testThread

         I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000

*/


class testThread implements Runnable{

 public void run()
 {
     for(int i=0;i<1000000;i++){} //a simple delay block to clarify.

     System.out.println("I am done executing run method of testThread");

 }  
}

public class mainClass{

   public static void main(String [] args)
    {
          testThread r = new testThread();
          Thread t1 = new Thread(r);
          t1.start();  /* Question is: can we call instead t1.run() */  
          System.out.println("I am the main thread , i created thread t1 and had it execute run method, which is currently looping for i to 1000000");

    }
}
Mainmast answered 16/10, 2011 at 15:45 Comment(0)
J
5

When you want it to run synchronously. Calling the run method won't actually give you multi-threading. The start method creates a new thread which calls the run method.

Jinnah answered 4/11, 2008 at 18:24 Comment(0)
T
3

If you want to execute the contents of run() like you would of any other method. Not to start a thread, of course.

Twentieth answered 4/11, 2008 at 18:25 Comment(0)
C
3

Assuming that you know the start and run method usage i.e. synchronous vs. asynchronous; run method can be used just to test the functionality.

Plus in some circumstances, the same thread class can be used in two different places with synch and asynch functionality requirements by having two different objects with one's run method and other's start method being invoked.

Charissa answered 4/11, 2008 at 18:34 Comment(0)
G
2

At least in the JVM 1.6., there's a bit of checking and run is called natively:

 public synchronized void start() {
        /**
     * This method is not invoked for the main method thread or "system"
     * group threads created/set up by the VM. Any new functionality added 
     * to this method in the future may have to also be added to the VM.
     *
     * A zero status value corresponds to state "NEW".
         */
        if (threadStatus != 0)
            throw new IllegalThreadStateException();
        group.add(this);
        start0();
        if (stopBeforeStart) {
        stop0(throwableFromStop);
    }
    }

    private native void start0();
Garrulity answered 4/11, 2008 at 18:35 Comment(0)
S
2

Just a note to the above great comments: sometimes your write a multi-thread code which uses "start" method to run different threads. You will find it much easier if you use "run" (instead of "start) for debugging since it makes the code to run synchronously and debugging it much easier.

Smelser answered 10/9, 2012 at 14:2 Comment(0)
N
0
public class TestClass implements Runnable {
    public static void main(String[] args) {
        TestClass tc = new TestClass();

        Thread t1 = new Thread(tc);
        System.out.println("Before Starting Thread " + Thread.currentThread().hashCode());
        t1.start();
        System.out.println("After Starting Thread " + Thread.currentThread().hashCode());
    }

    @Override
    public void run() {
        System.out.println("TestClass Run method is  Running with thread " + Thread.currentThread().hashCode());        
    }
}
Nashoma answered 15/2, 2015 at 10:48 Comment(2)
Hi Frnz, Check Out and Run the above example to understand clearly first run with t1.start() and see hashcode and next time with t1.run() and chk hashcodesNashoma
Where is your question?Higherup

© 2022 - 2024 — McMap. All rights reserved.