I want to know how and when does a Thread move back and forth between runnable and running states.What actually happens behind the scenes.I guess this will be needed in case of ThreadPool but I am not able to understand entirely.Please help me to understand this.
if thread is in running state that means its executing run() method and when its in runnable method its executing start() method....so I guess moving from running to runnable means its going back from run() to start()
In the nomenclature of most operating systems, "running" means that the thread actually is executing instructions on some CPU, and "runnable" means that nothing prevents the thread from "running" except the availability of a CPU to run on.
A Java program can not tell the difference between those two states. The thread states that Java knows about are NEW, RUNNABLE, BLOCKED, WAITING, TIMED_WAITING, and TERMINATED.
A thread is NEW before t.start() is called, and it can never go back to NEW afterward. WAITING and TIMED_WAITING both mean that the thread is waiting for a notify() call in some other thread. BLOCKED means it is waiting for anything else (e.g., to enter a synchronized block), and TERMINATED means it's finished.
Yield is a static method that tells the currently executing thread to give a chance to the threads that have equal priority in the Thread Pool.
There is no guarantee that Yield will make the currently executing thread to runnable state immediately. Remember an important point that yield method does not make the thread to go to Wait or Blocked state. It can only make a thread from Running State to Runnable State.
Extract from A Programmer's Guide to Java SCJP Certification: Threads:
static void yield()
This method causes the current thread to temporarily pause its execution and, thereby, allow other threads to execute. It is up to the JVM to decide if and when this transition will take place.
static void sleep (long millisec) throws InterruptedException
The current thread sleeps for the specified time before it becomes eligible for running again.
final void join() throws InterruptedException
final void join(long millisec) throws InterruptedException
A call to any of these two methods invoked on a thread will wait and not return until either the thread has completed or it is timed out after the specified time, respectively.
void interrupt()
The method interrupts the thread on which it is invoked. In the Waiting-for-notification, Sleeping, or Blocked-for-join-completion states, the thread will receive an InterruptedException.
Below Example illustrates transitions between thread states. A thread at (1) sleeps a little at (2) and then does some computation in a loop at (3), after which the thread terminates. The main() method monitors the thread in a loop at (4), printing the thread state returned by the getState() method. The output shows that the thread goes through the RUNNABLE state when the run() method starts to execute and then transits to the TIMED_WAITING state to sleep. On waking up, it computes the loop in the RUNNABLE state, and transits to the TERMINATED state when the run() method finishes.
Example :Thread States
public class ThreadStates {
private static Thread t1 = new Thread("T1") { // (1)
public void run() {
try {
sleep(2); // (2)
for(int i = 10000; i > 0; i--); // (3)
} catch (InterruptedException ie){
ie.printStackTrace();
}
}
};
public static void main(String[] args) {
t1.start();
while(true) { // (4)
Thread.State state = t1.getState();
System.out.println(state);
if (state == Thread.State.TERMINATED) break;
}
}
}
Possible output from the program:
RUNNABLE
TIMED_WAITING
...
TIMED_WAITING
RUNNABLE
...
RUNNABLE
TERMINATED
Related
I'm reading the book Oracle Certified Professional Java SE 7 Programmer Exams 1Z0-804 and 1Z0-805. One of the question asks the output of this code
class ThreadTest {
public static void main(String []args) throws InterruptedException {
Thread t1 = new Thread() {
public void run() { System.out.print("t1 "); }
};
Thread t2 = new Thread() {
public void run() { System.out.print("t2 "); }
};
t1.start();
t1.sleep(5000);
t2.start();
t2.sleep(5000);
System.out.println("main ");
}
}
The book says that it will always output t1 t2 main because TIMED_WAITING state can be only reach from RUNNABLE state.
But I was thinking that a thread can exit a RUNNABLE state without having executed a single instruction.
The doc says:
A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.
Is the answer of the book correct? And is it possible to exit the RUNNABLE state without having executed a single instruction?
I don't believe the book is correct, but for different reasons.
First off let's deal with your question directly. The only way to change out of RUNNABLE state is by executing an instruction which results in its state changing. This instruction might call a method (which happens to be synchronized and the thread then waits for a lock in BLOCKED) or return from the run() method (causing the thread to become TERMINATED). But these state changes always happen because the thread has done something to change its own state.
Edit - Just to elaberate on this; the method public void run() {} contains precisely one instruction: return. The thread must execute the return to get from RUNNABLE to TERMINATED.
The book is wrong (sort of). In "normal cases" 5 seconds is easily long enough to kick off a thread. But there is nothing synchronizing the threads and so nothing forcing the threads to do things in any particular order.
The the flow is:
The main thread kicks off t1.
The main thread then goes to sleep for 5 seconds. You would hope that 5 seconds is long enough for the OS to start a thread, but there is no guarantee that it will. If the OS is currently under attack from a fork bomb it might not have the resources to start the new thread.
The main thread then kicks off t2. If the OS is all clogged up and t1 hasn't started yet, there's no guarantee that t2 will not start (execute some code) first.
The main thread then goes to sleep for 5 seconds.
The main thread then prints "main ". Again if the OS is clogged up, this might actually happen before t1 or t2 start.
Never rely on a sequence of multiple threads without using synchronization!
I am playing around with the timed version of wait() in java.lang.Object and have observed that it acts differently in two different scenarios.
Scenario1: Using the default definition of run() in Thread
public static void main (String[] args) throws InterruptedException {
Thread t = new Thread();
t.start();
System.out.print("X");
synchronized(t) { t.wait(10000);}
System.out.print("Y");
}
Questions on scenario1: I am experiencing a delay between X and Y. Is this because I am calling wait() from main (even though, on t) and therefore the call stack of the main thread is being used, rather than that of the second thread?
Scenario2: Subclassing Thread on-the-fly to override run() in order to print something.
public static void main (String[] args) throws InterruptedException {
Thread t = new Thread() {public void run()
{System.out.print("I am the second thread.");}};
t.start();
System.out.print("X");
synchronized(t) { t.wait(10000);}
System.out.print("Y");
}
Questions on scenario2: I am NOT experiencing any delay at all! What has changed just because I have overridden run()? Now, each time I run the program it immediately prints "XI am the second thread.Y" without any delay, whatsoever! Where has the effect of wait() gone?
You have actually run into exactly why you should NEVER call wait or notify(All) on Thread (see the JavaDocs for Thread). Internally, Thread uses wait and notifyAll to implement Thread.join(), so what's happening in the second case is you thread enters wait, but then the other thread dies and calls notifyAll(), which wakes up your main thread.
Use Thread.sleep if you just want to wait for an elapsed time, use Thread.join if you actually want to wait for the thread’s termination. Also, read the javadocs in Object for proper usage of wait, notify, and notifyAll.
javaDoc:
public final void join(long millis)
throws InterruptedException
Waits at most millis milliseconds for this thread to die. A timeout of
0 means to wait forever. This implementation uses a loop of this.wait
calls conditioned on this.isAlive. As a thread terminates the
this.notifyAll method is invoked. It is recommended that applications
not use wait, notify, or notifyAll on Thread instances.
The explanation about how the thread finishing sends a notifyAll is relevant and correct, +1 from me. I'll try to add some information about why this is relevant.
When you call
synchronized(t) { t.wait(10000);}
in the main thread, it is the main thread that does the waiting. t is the monitor that the main thread is waiting on. Your expectation that this should make your t thread go dormant is mistaken.
The monitor here (the shared object being locked on, which happens to be t) is used to communicate between the different threads, a thread calls notifyAll on the monitor and the other threads waiting on the monitor receive the notification. You can think of the monitor as a shared communication point.
In your first example, the thread t starts and finishes immediately (because it doesn't have anything to do). The thread finishes and sends its notification before the main thread starts waiting, so you see a delay until the wait times out.
In the second example, the thread t has something to print, there's a race condition between it and the main thread. It's a free-for-all, what happens first depends on accidents of timing. What you're seeing is that the thread t now has to print a line to the console, so it manages to keep busy long enough that it's still alive at the time the main thread starts to wait, allowing the main thread to receive the notification when t finishes, causing the main thread to cut its wait short.
I was reading about thread synchronisation and wait/notify constructs from the tutorial. It states that
When wait is invoked, the thread releases the lock and suspends execution. At some future time, another thread will acquire the same lock and invoke Object.notifyAll, informing all threads waiting on that lock that something important has happened.
Some time after the second thread has released the lock, the first thread reacquires the lock and resumes by returning from the invocation of wait.
AFAIK, if there are multiple threads which can compete for the lock when the first thread is awaken by the notify, any one of them can get to own the lock on that object. My question is, if this first thread itself re-acquires the lock, does it have to start all over from the beginning of the synchronized method (which means, it again executes the code before the while loop checking wait() condition) or does it just pause at the wait() line?
// Does the waiting thread come back here while trying to own the
// lock (competing with others)?
public synchronized notifyJoy() {
// Some code => Does this piece of code gets executed again then in case
// waiting thread restarts its execution from the method after it is notified?
while (!joy) {
try {
// Does the waiting thread stay here while trying to re-acquire
// the lock?
wait();
} catch(InterruptedException e) {}
}
// Some other code
}
A method only gets exited when the thread executing it finishes executing its run method, whether by returning normally or having an exception be thrown that goes uncaught within that run method. The only way for your method to not get executed until one of those things above happens is for the JVM to be killed out from under you (with java.lang.System.exit, killing the java process with kill -9, etc.), or if the method is being run in a daemon thread where the JVM is shutting down. There's nothing weird going on here. The thread that waits gives up the lock and goes dormant, but it doesn't somehow leave off executing the method.
The thread awakened from its call to wait never went anywhere; the whole time that the thread was waiting it was still in the wait method. Before it can leave the wait method it first has to acquire the lock that it gave up in order to start waiting. Then it needs to retest whatever condition it needs to check before it can know whether to keep on waiting.
This is why the guarded blocks tutorial tells you that waits have to be done in a loop:
The invocation of wait does not return until another thread has issued a notification that some special event may have occurred — though not necessarily the event this thread is waiting for:
public synchronized void guardedJoy() {
// This guard only loops once for each special event, which may not
// be the event we're waiting for.
while(!joy) {
try {
wait();
} catch (InterruptedException e) {}
}
System.out.println("Joy and efficiency have been achieved!");
}
Note: Always invoke wait inside a loop that tests for the condition being waited for. Don't assume that the interrupt was for the particular condition you were waiting for, or that the condition is still true.
(The wording used by the tutorial is misleading; the word "interrupt" should be "notification". Also it is unfortunate that the tutorial code shown eats the InterruptedException without setting the interrupt flag, it would be better to let the InterruptedException be thrown from this method and not catch it at all.)
If the thread did "start over" then this loop wouldn't be required; your code would start at the beginning of the method, acquire the lock, and test the condition being waited on.
Thread execution starts directly after the call to wait. It does not restart the block from the beginning. wait() can be roughly implemented similar to
public void wait() {
release_monitor();
wait_monitor();
acquire_monitor();
}
This is no where near how it is actually implemented, it is just a rough idea of what goes on behind the scenes. Each Object has a monitor associated with it that can acquired and released. Only one thread can hold the monitor at a time and a thread can acquire a monitor recursively with no issue. A call to wait on an Object releases the monitor allowing another thread to acquire it. The waiting thread then waits until it is woken up by a call to notify/notifyAll. Upon being woken up the waiting thread waits again to require the Object's monitor and returns to the calling code.
Example:
private Object LOCK = new Object;
private int num = 0;
public int get() {
synchronized( LOCK ) {
System.out.println( "Entering get block." );
LOCK.wait();
return num;
}
}
public void set( int num ) {
synchronized( LOCK ) {
System.out.println( "Entering set block." );
this.num = num;
LOCK.notify();
}
}
"Entering get block." will only be printed once for each call to get()
I have one question regarding wait/notify based threads interaction.
The output of the below code is Im. How output can be Im as there is no other thread calling notify() on Thread object. Is it like JVM implicitly calls notify() in above such scenarios where you try to wait on Thread class instance.
A thread operation gets stuck when it waits without receiving any notification. Now what if I wait on Thread class instance wait(). For e.g.
public class WaitingThread {
public static void main(String[] args) {
Thread t1 = new Thread();
t1.start();
synchronized (t1) {
try {
t1.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("Im");
}
}
Your program is leaving wait() because the thread is finishing immediately. This is a byproduct of the Thread library that the Thread object is notified when the thread finishes. This is how join() works but it is not behavior that should be relied on since it is internal to the thread sub-system.
If you are trying to wait for the thread to finish then you should be using the t1.join() method instead.
Your thread is finishing immediately because it does not have a run() method defined so it is started and finishes. Really it is a race condition and the thread that is started could finish before the main thread gets to the wait() method call. You can see this if you put a short sleep (maybe 10ms) after the start() is called. Then you can see that you program will sit in wait() forever.
What is the difference between thread state WAIT and thread state BLOCKED?
The Thread.State documentation:
Blocked
A thread that is blocked waiting for a monitor lock is in this state.
Waiting
A thread that is waiting indefinitely for another thread to perform a particular action is in this state
does not explain the difference to me.
A thread goes to wait state once it calls wait() on an Object. This is called Waiting State. Once a thread reaches waiting state, it will need to wait till some other thread calls notify() or notifyAll() on the object.
Once this thread is notified, it will not be runnable. It might be that other threads are also notified (using notifyAll()) or the first thread has not finished his work, so it is still blocked till it gets its chance. This is called Blocked State. A Blocked state will occur whenever a thread tries to acquire lock on object and some other thread is already holding the lock.
Once other threads have left and its this thread chance, it moves to Runnable state after that it is eligible pick up work based on JVM threading mechanism and moves to run state.
The difference is relatively simple.
In the BLOCKED state, a thread is about to enter a synchronized block, but there is another thread currently running inside a synchronized block on the same object. The first thread must then wait for the second thread to exit its block.
In the WAITING state, a thread is waiting for a signal from another thread. This happens typically by calling Object.wait(), or Thread.join(). The thread will then remain in this state until another thread calls Object.notify(), or dies.
The important difference between the blocked and wait states is the impact on the scheduler. A thread in a blocked state is contending for a lock; that thread still counts as something the scheduler needs to service, possibly getting factored into the scheduler's decisions about how much time to give running threads (so that it can give the threads blocking on the lock a chance).
Once a thread is in the wait state the stress it puts on the system is minimized, and the scheduler doesn't have to worry about it. It goes dormant until it receives a notification. Except for the fact that it keeps an OS thread occupied it is entirely out of play.
This is why using notifyAll is less than ideal, it causes a bunch of threads that were previously happily dormant putting no load on the system to get woken up, where most of them will block until they can acquire the lock, find the condition they are waiting for is not true, and go back to waiting. It would be preferable to notify only those threads that have a chance of making progress.
(Using ReentrantLock instead of intrinsic locks allows you to have multiple conditions for one lock, so that you can make sure the notified thread is one that's waiting on a particular condition, avoiding the lost-notification bug in the case of a thread getting notified for something it can't act on.)
Simplified perspective for interpreting thread dumps:
WAIT - I'm waiting to be given some work, so I'm idle right now.
BLOCKED - I'm busy trying to get work done but another thread is standing in my way, so I'm idle right now.
RUNNABLE...(Native Method) - I called out to RUN some native code (which hasn't finished yet) so as far as the JVM is concerned, you're RUNNABLE and it can't give any further information. A common example would be a native socket listener method coded in C which is actually waiting for any traffic to arrive, so I'm idle right now. In that situation, this is can be seen as a special kind of WAIT as we're not actually RUNNING (no CPU burn) at all but you'd have to use an OS thread dump rather than a Java thread dump to see it.
Blocked- Your thread is in runnable state of thread life cycle and trying to obtain object lock.
Wait- Your thread is in waiting state of thread life cycle and waiting for notify signal to come in runnable state of thread.
see this example:
demonstration of thread states.
/*NEW- thread object created, but not started.
RUNNABLE- thread is executing.
BLOCKED- waiting for monitor after calling wait() method.
WAITING- when wait() if called & waiting for notify() to be called.
Also when join() is called.
TIMED_WAITING- when below methods are called:
Thread.sleep
Object.wait with timeout
Thread.join with timeout
TERMINATED- thread returned from run() method.*/
public class ThreadBlockingState{
public static void main(String[] args) throws InterruptedException {
Object obj= new Object();
Object obj2 = new Object();
Thread3 t3 = new Thread3(obj,obj2);
Thread.sleep(1000);
System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+
",when Wait() is called & waiting for notify() to be called.");
Thread4 t4 = new Thread4(obj,obj2);
Thread.sleep(3000);
System.out.println("nm:"+t3.getName()+",state:"+t3.getState().toString()+",After calling Wait() & waiting for monitor of obj2.");
System.out.println("nm:"+t4.getName()+",state:"+t4.getState().toString()+",when sleep() is called.");
}
}
class Thread3 extends Thread{
Object obj,obj2;
int cnt;
Thread3(Object obj,Object obj2){
this.obj = obj;
this.obj2 = obj2;
this.start();
}
#Override
public void run() {
super.run();
synchronized (obj) {
try {
System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before Wait().");
obj.wait();
System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After Wait().");
synchronized (obj2) {
cnt++;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Thread4 extends Thread{
Object obj,obj2;
Thread4(Object obj,Object obj2){
this.obj = obj;
this.obj2 = obj2;
this.start();
}
#Override
public void run() {
super.run();
synchronized (obj) {
System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",Before notify().");
obj.notify();
System.out.println("nm:"+this.getName()+",state:"+this.getState().toString()+",After notify().");
}
synchronized (obj2) {
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}