wood burning stoves 2.0*
The moose likes Programmer Certification (SCJP/OCPJP) and the fly likes JVM and Thread Help Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Programmer Certification (SCJP/OCPJP)
Bookmark "JVM and Thread Help" Watch "JVM and Thread Help" New topic
Author

JVM and Thread Help

Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944
Friends:
I am using this forum for the first time.
Please help me.
1. JVM exits once all the non daemon threads have died. // True
2. JVM exits once main method exits //?? Not sure, I feel True
Are the answers right. Can some one provide some explaination. I tried looking in RHE.
Regards
J2user.
raghavendra
Greenhorn

Joined: Apr 12, 2000
Posts: 16
My thought is that, after exiting the main method, only daemon threads will be left. so the JVM goes ahead and terminates execution.
maha anna
Ranch Hand

Joined: Jan 31, 2000
Posts: 1467
j2user,
Welcome. Please do register.
JVM exits once main method exits
This is NOT TRUE. The reason is , the thread which runs the main(String[] args) method,( I assume here 'main' means the entry-point method for any Java appln.) can create 1 or more threads . Assume that the main method's thread creates 2 more threads and starts them. Also know that apart from these 3, (1 main's thread+2 created threads by main's thread) there are other system thread (so called daemon threads) which are in fact service threads which help runnning the application. For example the GUI thread, GC thread etc.
So all the thread are running in this application. We CAN NOT gurantee that all threads will finish up at the same time OR in fact the child thread created by the main's thread will finish at all. What if one of the child threads is suspended ? What if one of the child threads is waiting for something to happen? What if the child thread is in fact doing a time-consuming work and not yet finished? The main's thread could have finished earlier. Does it means JVM abrubts the child thread's work and terminates? Not at all. The JVM waits until all the user thread are done and happy. If there is no gurantee that a thread may be terminated by JVM then what's the use of creating a thread itself , afraid of may be stopped at any time? Then there is no reliable functionality at any time right? One thread's functionalty depens on other if it were the case.
The JVM exits when all the users threads are finished successfully and left over are ONLY the servicing threads from JVM.
See the concept in action now.
<pre>

class Test {
public static void main(String[] args) throws Exception{
UserThread thread1 = new UserThread();
UserThread thread2 = new UserThread();
thread1.start();
thread2.start();
System.out.println("Hello all. Main(String[]) end in 1 sec. :-)");
Thread.sleep(1000);
}

}
class UserThread extends Thread {
public void run() {
for (;; ) {
System.out.println(Thread.currentThread().getName()+" : I am alive");
try {
sleep(1000);
}catch(InterruptedException e) {
}
}
}
}

</pre>
regds
maha anna

[This message has been edited by maha anna (edited April 20, 2000).]
Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944

Maha:
Are you saying that the mail() thread dies after
1000 millisecs. I ran your code and it looks like
the two threads which are created are alive and kicking
(go into an infinite loop).
Am I right about the main thread ?
Regds.
- satya
gunjan
Ranch Hand

Joined: Jan 28, 2000
Posts: 33
Hi:
So the child thread can keep kicking even when the parent dies.
FYI, JVM also dies when the System.exit or exit method of Runtime is called.
Regards
Gunjan

Regards<BR>Gunjan
maha anna
Ranch Hand

Joined: Jan 31, 2000
Posts: 1467
Satya,
It is a very good qstn. We have to differentiate between the main(String[] arg) method and the Thread which runs the main(String[] args) method. We have to keep this info in mind when we discuss about Threads. Each thread belongs to a ThreadGroup. The enumerate(..) fn returns the total no of threads in the ThreadGroup and its subgroups. In order to know what really happens in the above program I slightly changed the code to printout the Threadname and the total no of threads in the threadgruop and each individual thread's name. In the foll. code I had put 'Maha's comments' as a running commentry.
It is quite interesting to see the results. You all also enjoy it. The bottom line is If a parent thread creates some child threads and starts, them eventhoug the parent thread finishes its work ,[NOTE Here carefully. executing the main(String[] srgs) method alone is the work of the main(..) method's thread. (the parent thread ] it WAITS for its children threads to finish. I am showing this with the foll. code. I am giving the output also for your reference.
So the bottom line is JVM DOES NOT exit when the main()method exits. It exits when ALL THE NON-DAEMON (user) threads finish.
<pre>

/* Maha's Bench Mark of the results
//All 3 user threads switches

main//Total 5 (3 user +2 daemon)
thread 0//Total 5 (3 user +2 daemon)
thread 1//Total 5 (3 user +2 daemon)
main//Total 5 (3 user +2 daemon)
thread 0//Total 5 (3 user +2 daemon)
thread 1//Total 5 (3 user +2 daemon)

//look carefully here. main(..)'s Thread finished it's work.
//But still it waits for it's children to finish
//Evidence is the Total val remains SAME
//See here.Now, only the other 2 user threads swithes

thread 0//Total 5 (3 user +2 daemon)
thread 1//Total 5 (3 user +2 daemon)
thread 0//Total 5 (3 user +2 daemon)

//See here. Thread 0 finished (it slept for 4 secs..
//So Now the Toatal = 4 . Only 4 are left in
//Thread 1's group. 2 daemon + 1 parent
(main) + 1 user (thread 1)

thread 1//Total 4 (2 user +2 daemon)
*/
ThreadName =main ActiveCount = 5
Thread[main,5,main] is NOT Daemon Thread
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-0,5,main] is NOT Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
ThreadName =Thread-0 ActiveCount = 5
Thread[main,5,main] is NOT Daemon Thread
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-0,5,main] is NOT Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
ThreadName =Thread-1 ActiveCount = 5
Thread[main,5,main] is NOT Daemon Thread
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-0,5,main] is NOT Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
ThreadName =main ActiveCount = 5
Thread[main,5,main] is NOT Daemon Thread
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-0,5,main] is NOT Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
ThreadName =Thread-0 ActiveCount = 5
Thread[main,5,main] is NOT Daemon Thread
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-0,5,main] is NOT Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
ThreadName =Thread-1 ActiveCount = 5
Thread[main,5,main] is NOT Daemon Thread
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-0,5,main] is NOT Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
ThreadName =Thread-0 ActiveCount = 5
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-0,5,main] is NOT Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
Thread[Thread-2,5,main] is NOT Daemon Thread
ThreadName =Thread-1 ActiveCount = 5
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-0,5,main] is NOT Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
Thread[Thread-2,5,main] is NOT Daemon Thread
ThreadName =Thread-0 ActiveCount = 5
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-0,5,main] is NOT Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
Thread[Thread-2,5,main] is NOT Daemon Thread
ThreadName =Thread-1 ActiveCount = 4
Thread[SymcJIT-LazyCompilation-0,1,main] is Daemon Thread
Thread[SymcJIT-LazyCompilation-PA,10,main] is Daemon Thread
Thread[Thread-1,5,main] is NOT Daemon Thread
Thread[Thread-2,5,main] is NOT Daemon Thread
</pre>
regds
maha anna

[This message has been edited by maha anna (edited April 20, 2000).]
maha anna
Ranch Hand

Joined: Jan 31, 2000
Posts: 1467
And here is the programe for you to test and see the above results.
Jim,
I want your valuable feed back on this ,and the main qstn by j2user which started all this discussion.
regds
maha anna
<pre>


class Test {
public static void main(String[] args) throws Exception{
UserThread thread1 = new UserThread();
UserThread thread2 = new UserThread();
thread1.start();
thread2.start();
for (int i = 0; i < 2; i++) {
Test.printAllThreadsInThisThreadGroup(Thread.currentThread());
Thread.sleep(1000);
}
}
static void printAllThreadsInThisThreadGroup( Thread thread) {
System.out.println("");
System.out.println("ThreadName ="+thread.getName()
+ " ActiveCount = " + thread.activeCount());
System.out.println("");
Thread[] tArray = new Thread[thread.activeCount()];
thread.enumerate(tArray);
for(int i = 0; i < tArray.length; i++) {
if(((Thread)tArray[i]).isDaemon()) {
System.out.println((Thread)tArray[i] +" is Daemon Thread ");
}
else {
System.out.println((Thread)tArray[i] +" is NOT Daemon Thread ");
}
}
}
}
class UserThread extends Thread {
public void run() {
for (int i=0; i<4; i++) {
try {
sleep(1000);
Test.printAllThreadsInThisThreadGroup(Thread.currentThread());
}catch(InterruptedException e) {
}
}
}
}

</pre>
[This message has been edited by maha anna (edited April 20, 2000).]

[This message has been edited by Jim Yingst (edited April 20, 2000).]
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Hi Maha- I just did some minor editing above because one of the println lines was so long that it caused a scroll bar to appear on my browser - so I split it into two lines.
As for the questions: hmmm, very strange. It does look as though the original main thread is hanging around longer than it needs to, and I don't understand why. But I would agree that even if the main method exits and that thread terminates, the other UserThreads can keep going, and that will prevent the JVM from exiting. Sorry I don't have time right now to investigate further - I played with your code a bit and saw some things I can't explain, so I definitely want to get back to it - but now's not a good time. See you later...


"I'm not back." - Bill Harding, Twister
Anonymous
Ranch Hand

Joined: Nov 22, 2008
Posts: 18944

Maha:
I did attempt to understand the point. But to be honest,
currently, it is a little above my head. However, I will
tune in later on and I am sure to understand it better.
Also, I will see what Jim says later on ...
Regds.
- satya
nirvan sage
Greenhorn

Joined: Feb 20, 2000
Posts: 24
I have some really big doubts about this but do allow me to state my reasonings
Lets begin with the main method it has brought thread t1 into a runnable state,now that does not necessarily causes its immediate execution. The program execution continues within the main method which eventually causes thread t2 to be made runnable. The execution ofcourse continues with the main thread unless you put it to sleep which hasnt been done and so it encounters a for loop and jumps into it and causes the

function to be executed which prints out

and returns back to the call and goes to sleep for 1 second so now the other threads get a chance and jump into action
and thus printing

I presume these two threads are thread1 and thread2 By now the main thread will have switched from its Block to ready state after
which control switches to it thus causing the statement below to be printed out

after which it goes to sleep for 1 second following which it must exit but in the later stages we see the presence of a Thread-2 which I believe is the main Thread waiting for its exit. I would like to point out one more thing thread1 and thread2 only gets to call

4 times Thread-0 has already occured 4 times so it must have exited by the time Thread-1 gets to call printAllThreads...()
and there is no chance for it be present.So I think the presence of the Thread-1 and Thread-2 in the last set of statements are actually the non daemon threads and the main thread
Besides causing an infinite loop inside the run method will cause the presence of 5 activecounts as long as the program runs
How is that possible ?Please do help in this regard

[This message has been edited by nirvan sage (edited April 22, 2000).]
Javix Protocol
Ranch Hand

Joined: Mar 21, 2000
Posts: 57
So do u mean to tell that the main method exits only after all the non-deamon threads have exited.
------------------
The Javix


Write Once , Run Anytime ,Anywhere Forever And Smile Happily.
maha anna
Ranch Hand

Joined: Jan 31, 2000
Posts: 1467
The main(String[] args) method finishes its job. THis method exits. But the theread which is running this main(String[] args) method ends only after the child user threads it created. In other words let's say the thread name which runs the main(Stirng[] args) methos is main thread . Then if this main thread creates Thread1 and Thread 2, then the main thread waits untill all its children threads Thread 1 and Thread 2 end. But the work of the main thread which in our case here is just executing the main(String[] args) method alone is done .
regds
maha anna
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: JVM and Thread Help