Raj
Raj

Reputation: 75

Thread Contention in java

I am trying to understand below program. If I call new ReaderThread().start() it is working fine, but if I call new ReaderThread().run(), the application goes into an infinite loop. What is the difference?

public class Contention {

    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
                 while (!ready){
                System.out.println("ready ..."+ready);
                Thread.yield();}
            System.out.println(number);
           // }
        }
    }


    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new ReaderThread().run();
        number = 42;
        ready = true;

    }

}

Upvotes: 3

Views: 1225

Answers (6)

Rakesh
Rakesh

Reputation: 4334

If you use new ReaderThread().start();,you are creating actually a new thread instance which will run in the background and main() resumes with its further execution.

But new ReaderThread().run(); creates an instance of this class and makes a normal method call to the run() method, so the main() has to wait till the run() has finished executing and returned the control back to main(), which in your case is an infinite loop.

If you want to start a new thread then start by using ReaderThread().start(); this is the correct way to start a thread, there are no alternatives for this.

Upvotes: 2

Prabath Siriwardena
Prabath Siriwardena

Reputation: 5921

When you have new ReaderThread().run(); it's in the same thread and ready = true; never reached.

But when you call new ReaderThread().start() it starts a new thread and main thread also continue and will hit ready = true; - which will take the thread created out of the loop...

Upvotes: 1

Peter Lawrey
Peter Lawrey

Reputation: 533520

when you call run() you do so in the same thread. Its just a method call.

When you call start() to a triggering another Thread to call run()

This is one of the reasons its not a good idea to extend Thread, but instead implement Runnable which you wrap with a thread. This is one of the many potential sources of confusion.


Here is a related teaser for you

static String name = "Peter Lawrey";
static String state = "Washington";

static String getName() {
  return name;
}

static String getState() {
  return state;
}

static class NamedThread extends Thread {
  @Override
  public void run() {
    System.out.println(getName()+" - "+getState());
  }
}

public static void main(String... args) throws InterruptedException {
  new NamedThread().start();
}

prints

Thread-0 - RUNNABLE

Can you work out why?

Upvotes: 11

ngesh
ngesh

Reputation: 13501

public class Contention {

    private static boolean ready;
    private static int number;

    private static class ReaderThread extends Thread {
        public void run() {
                 while (!ready){
                System.out.println("ready ..."+ready);
                Thread.yield();}
            System.out.println(number);
           // }
        }
    }




    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        new ReaderThread().run();//control goes to run() method

//and it keeps running and next line of code where you set ready=true will not be executed
        number = 42;
        ready = true;

    }

}

edited:

because Threads don't run together (but concurrently), but OS decides which one runs and it makes sure that every thread gets its own chance based on TimeShared basis (or any algorithm). so may be in your case the other thread gets chance first and it gets executed before main() thread gets a chance to run and set ready = true. but if you run your code again the other case is also possible. where ready = true; is set and Thread wont enter While() loop.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1500525

run() is just a method which won't start a new thread - so main() will never get to set ready to true.

Only start() will actually spawn a separate thread of execution - which is what you need.

Note that even with this, your code isn't guaranteed to work due to memory model concerns - you need to worry about the visibility of the changes you make to shared data.

Upvotes: 4

Illarion Kovalchuk
Illarion Kovalchuk

Reputation: 5894

Read carefully about threads in java (for example http://download.oracle.com/javase/tutorial/essential/concurrency/)

When you call method run(), you call it just as any other method and it will work in the same thread as calling method.

Upvotes: 2

Related Questions