Reputation: 75
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
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
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
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
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
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
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