Hi All
I got too many mails. Thanks all of you. Almost everyone is asking me about threads. The concern about threads could be understood, as it seems the toughest. So I thought I might share whatever little I could, regarding thread in the benefit of the group.
The thread has various states, new state, Runnable (ready-to run), Running, Blocked, Waiting pool, Lock pool, dead etc. (I have a nice diagram showing various stateo fthread, but I am unable to copy it here. Any Help!!!)
New State
When a thread is created, it is said to be in new state. Remember, when a thread is created, it does not start execution. The thread can be created by either creating a subclass of java.lang.Thread or by creating a class, which implements the interface java.lang.Runnable. In either case, override the public void run() method and define the code which you expect to be executed while the thread is running. REMEMBER THE SIGNATURE OF THE run() METHOD.
When the thread is in new state, the isAlive() method will return false. When the thread is created, its priority is set to the priority of the thread which created the thread.
Runnable (Ready-To-run)
When start() method called on new thread, the thread becomes Runnable. Remember that the thread does not start execution when the start() method is called. It may happen that it may not start forever (another running thread calls System.exit ()).
Remember, the start() method dose not call the run() directly, the Java Virtual Machine calls the run method of this thread. What it does is probably register the thread with thread scheduler (RHE). It throws IlleagleThreadStateException , if the thread was already started.
There are other scenarios also, where a thread becomes Runnable, which we will see later.
Running
When the thread is running, it executes code which is defined in the run() method. When the thread will run, can never be guaranteed. This depends on thread scheduler and which, in turn, depends on the underlying OS.
The model of preemptive scheduler is that many threads might be runnable, but only one thread is actually running. This thread continues to run until it ceases to be runnable or another thread of higher priority becomes runnable. In case of timesliced, equal amount of CPU time is given to each thread.
The JVM exits when all the working threads daemon threads or System.exit(0) is called.
Now consider the following code. Try to compile and run this code. How many times the value of i is printed? Now initialize the value of I at declaration time only and see the result. Now declare the variable i in the method itself instead of making it instance variable. See the result. This will give an idea about different possibilities regarding value of instance variable which are changed by different threads.
class TestThread{
public static void main(String args []){
Thread1 t1 = new Thread1();
Thread th1 = new Thread(t1);
Thread th2 = new Thread(t1);
th1.start();
th2.start();
}
}// End of TestThread
class Thread1 implements Runnable{
int i;
public void run(){
i = 0;
while(true){
System.out.println("Value of i = " + i++);
if ( i == 10)
break;
}
}
}
Dead Thread
When the execution of the run() method is over, the thread becomes dead thread. The dead thread can�t be started again. However the variables and methods of the dead thread can be accessed.
The stop() method also make the thread dead. Also if an exception is thrown and is uncaught, the thread becomes dead.
The isAlive () method will return false, if the thread is dead. Hence, the isAlive() method returns false only if the thread is in new state or is dead. All other time it returns true.
yield() � This is a static method. Use Thread.yield() to give other threads of the same priority a chance to execute. If other threads at the same priority are runnable, yield() places the calling thread into the Runnable pool and allows another thread to run. If no other threads are Runnable at the same priority, yield does nothing.
However, RHE mentions that there is no guarantee that when yield () is called, the thread with lower priority will not run. I tested the code, and it is found that the running thread doesn�t give up when yield is called and when only running threads are ones with lower priorities.
Blocked Thread
The Running thread can be blocked in many ways.
sleep(long time) - This is static method. It stops execution of the current thread and blocked for atleast the time as specified if it is not interrupted. The thread does not lose ownership of any monitors. Hence when the specified time is elapsed or the thread is interrupted, the thread becomes Runnable (not Running).
join() � The join method causes the current thread to wait until the thread on which the join method is called terminates or is interrupted or the specified time as argument to join method elapses.
I/O operation � if an executing thread calls any method which requires some input stream to be responded, then the thread waits for such input and hence is blocked. Any such blocking of thread will ensures that it releases the lock.
You may refer to following link to understand object lock, wait, notify, and interrupt, synchronization etc., as it provides very good explanation. Hence I thought no need to repeat the same.
http://www.javaranch.com/maha/Discussions/Threads/threads.html Following are some of the things, which I would like to highlight:
When a thread receives notify/notifyAll , it goes to Object�s Lock Pool i.e. waits for the object�s lock, and once it acquires the lock, it becomes Runnable.
Calls to interrupt() are stored i.e. if interrupt() is called on a thread which is not blocked by sleep, wait, join etc. and doing something else, then it will continue with the work. When the thread, on which interrupt () was called, calls any of the above-mentioned methods, it will be interrupted immediately.
Calls to notify are not stored. A notify call can be issued without regard to whether any threads are waiting. If the notify method is called on an object when no threads are blocked in the wait pool for that object�s lock, the call has no effect.
When notify call is executed on a particular object, an arbitrary thread is moved from object�s wait poll to a lock pool. There is no way you can ensure that a particular thread will be moved out of object�s wait pool.
Wait method releases the lock on the current object only. If it has also acquired locks on some other objects, it does not release those locks.
Sources: RHE, Student Guide from Sun Educational Services, API documentation, special thanks to Maha Anna for excellent explanation on this topic (see the above mentioned link)
Correct me wherever I am wrong.
Hope this will be of some use to all.
Mukesh
[This message has been edited by Mukesh Rathod (edited October 21, 2000).]