Author Topic:   JVM and Thread Help
j2user
unregistered
posted April 20, 2000 07:55 AM           
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
posted April 20, 2000 11:48 AM             
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
bartender
posted April 20, 2000 12:22 PM             
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.



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) {
}

}

}

}


regds
maha anna

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

satya5
ranch hand
posted April 20, 2000 01:24 PM             

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
posted April 20, 2000 02:38 PM         
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

maha anna
bartender
posted April 20, 2000 03:35 PM             
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.



/* 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

regds
maha anna

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

maha anna
bartender
posted April 20, 2000 03:36 PM             
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



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) {

}
}
}
}

[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
sheriff
posted April 20, 2000 06:33 PM             
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...

satya5
ranch hand
posted April 21, 2000 12:07 PM             

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
posted April 22, 2000 01:24 AM             
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

code:
printAllThreadsInThisThreadGroup(Thread.currentThread())


function to be executed which prints out

code:
ThreadName =main ActiveCount = 5  


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

code:

ThreadName =Thread-0 ActiveCount = 5 and
ThreadName =Thread-1 ActiveCount = 5


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
code:

ThreadName =main ActiveCount = 5

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

code:

printAllThreadsInThisThreadGroup(Thread.currentThread());

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
posted April 24, 2000 03:47 AM             
So do u mean to tell that the main method exits only after all the non-deamon threads have exited.

------------------
The Javix

maha anna
bartender
posted April 24, 2000 07:24 AM             
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

|