4

I'm a Java learner, trying to understand Threads.

I was expecting output from my program below, in the order

Thread started Run Method Bye

But I get output in the order

Bye Thread started Run Method

Here is my code:

public class RunnableThread
{
    public static void main(String[] args)
    {
        MyThread t1= new MyThread("Thread started");
        Thread firstThread= new Thread(t1);
        firstThread.start();
        System.out.println("Bye");
    }
}

class MyThread implements Runnable
{
    Thread t;
    String s= null;

    MyThread(String str)
    { 
      s=str;
    }

    public void run()
    {
      System.out.println(s);
      System.out.println("Run Method");
    }
}
paisanco
  • 4,098
  • 6
  • 27
  • 33
Spands
  • 107
  • 3

6 Answers6

4

In a multithreaded code there's no guarantee which thread will run in what order. That's in the core of multithreading and not restricted to Java. You may get the order t1, t2, t3 one time, t3, t1, t2 on another etc.

In your case there are 2 threads. One is main thread and the other one is firstThread. It's not determined which will execute first.

uylmz
  • 1,480
  • 2
  • 23
  • 44
3

This is the whole point of Threads - they run simultaneously (if your processor has only one core though, it's pseudo-simultaneous, but to programmer there is no difference).

When you call Thread.start() method on a Thread object it's similar (but not the same, as it's starting a thread, and not a process and former is much more resource consuming) simultaneously starting another java program. So firstThread.start() starts to run paralel to your main thread (which was launched by your main method).

This line starts a main execution thread (like a zeroThread)

public static void main(String[] args)

Which you can reference, by calling Thread.sleep() for example.

This line

firstThread.start();

Starts another thread, but in order to reference it you use it's name, but you reference it from the main thread, which is running paralel to firstThread. In order to get the expected output you can join these two threads, which is like chaining them: This way:

public static void main(String[] args)
{
    MyThread t1= new MyThread("Thread started");
    Thread firstThread= new Thread(t1);
    firstThread.start();
    firstThread.join();
    System.out.println("Bye");
}

join(), called on firstThread (by main thread) forces main thread to wait until the firstThread is finished running (it will suspend proceding to the next command, which is System.out.println("Bye");).

Kudin
  • 456
  • 4
  • 7
2

It appears that you seek the thread (and probably more than one) to run while main() waits for everything to finish up. The ExecutorService provides a nice way to manage this -- including the ability to bail out after a time threshold.

import java.util.concurrent.*;                                                   

class MyThread implements Runnable { // ... }                                    

class MyProgram {                                                                
  public static void main(String[] args)                                         
  {                                                                              
    MyThread t1 = new MyThread();                                            
    MyThread t2 = new MyThread();                                            
    MyThread t3 = new MyThread();                                            

    // At this point, 3 threads teed up but not running yet                  

    ExecutorService es = Executors.newCachedThreadPool();                    

    es.execute(t1);                                                          
    es.execute(t2);                                                          
    es.execute(t3);                                                          

    // All three threads now running async                                   

    // Allow all threads to run to completion ("orderly shutdown")            
    es.shutdown();                                                           

    // Wait for them all to end, up to 60 minutes.  If they do not 
    // finish before then, the function will unblock and return false:          
    boolean finshed = es.awaitTermination(60, TimeUnit.MINUTES);             

    System.out.println("Bye");                                               
  }                                                                            
}                                                                               
Buzz Moschetti
  • 7,057
  • 3
  • 23
  • 33
0

There is no specified order in which Java threads are accustomed to run. This applies for all threads including the "main" thread.

If you really want to see it working, try:

class RunnableThread
{
    public static void main(String[] args)
    {
        MyThread t1= new MyThread();
        Thread firstThread= new Thread(t1);
        firstThread.start();
        System.out.println("Thread Main");
        for(int i=1;i<=5;i++)
        {
            System.out.println("From thread Main i = " + i);
        }
        System.out.println("Exit from Main");
    }
}

class MyThread implements Runnable
{
    public void run()
    {
        System.out.println("Thread MyThread");
        for(int i=1;i<=5;i++)
        {
            System.out.println("From thread MyThread i = " + i);
        }
        System.out.println("Exit from MyThread");
    }
}
skrtbhtngr
  • 2,223
  • 23
  • 29
0

This is not a thread start order problem. Since you're really only starting a single thread.

This is really more of an API Call speed issue.

Basically, you have a single println() printing "bye", which gets called as soon as the Thread.start() returns. Thread.start() returns immediately after being called. Not waiting for the run() call to be completed.

So you're racing "println" and thread initializaiton after "thread.start()", and println is winning.

As a sidenote, and in general, you might want to try to use ExecutorService and Callable when you can, as these are higher level, newer APIs.

Community
  • 1
  • 1
kervin
  • 11,672
  • 5
  • 42
  • 59
  • Is thread.start() asynchronous? (i.e. it immediately returns without really starting thread) – uylmz Jun 14 '15 at 13:30
  • @Reek start() returns before run() is completed. It returns after the OS level work of starting the thread is completed. – kervin Jun 14 '15 at 13:35
  • Then after thread.start() returns, there are 2 threads. They may as well race now? – uylmz Jun 14 '15 at 13:36
  • Didn't say there wasn't a race. But it's not a thread start order problem. – kervin Jun 14 '15 at 13:40
0

When You start a Thread it will execute in parallel to the current one, so there's no guarantee about execution order.

Try something along the lines:

public class RunnableThread {
    static class MyThread implements Runnable {
        Thread t;
        String s= null;    
        MyThread(String str) { 
          s=str;
        }
        public void run() {
          System.out.println(s);
          System.out.println("Run Method");
        }
    }
    public static void main(String[] args) {
        MyThread t1= new MyThread("Thread started");
        Thread firstThread= new Thread(t1);
        firstThread.start();
        boolean joined = false;
        while (!joined)
            try {
                firstThread.join();
                joined = true;
            } catch (InterruptedException e) {}
        System.out.println("Bye");
    }
}
ZioByte
  • 2,690
  • 1
  • 32
  • 68