How can 'java' launch a multithreaded program?

P

Paul J. Lucas

I'm looking at the source code for the 'java' command-line tool
written in C. Near the bottom of main(), it calls the static
main() method of the main Java class via CallStaticVoidMethod().
It then detaches the current thread and destroys the JVM via
DestroyJavaVM().

The thing I don't understand is what if the Java main class's
main() spawns a thread, runs in that thread, whereas the
original thread returns from main() and dies. The call to
CallStaticVoidMethod() will then return and the C code will
continue, and then call DestroyJavaVM() effectively killing the
JVM out from under the still-running Java program.

This is what can happen in a Java Swing application where its
main() creates the AWT event thread and the application runs in
it, yet the original thread returns from main().

So how does this work? How is the call to DestroyJavaVM()
deferred?

- Paul
 
T

Thomas G. Marshall

Paul J. Lucas coughed up:
I'm looking at the source code for the 'java' command-line tool
written in C. Near the bottom of main(), it calls the static
main() method of the main Java class via CallStaticVoidMethod().
It then detaches the current thread and destroys the JVM via
DestroyJavaVM().

The thing I don't understand is what if the Java main class's
main() spawns a thread, runs in that thread, whereas the
original thread returns from main() and dies. The call to
CallStaticVoidMethod() will then return and the C code will
continue, and then call DestroyJavaVM() effectively killing the
JVM out from under the still-running Java program.

This is what can happen in a Java Swing application where its
main() creates the AWT event thread and the application runs in
it, yet the original thread returns from main().

So how does this work? How is the call to DestroyJavaVM()
deferred?

- Paul

Without actually looking at the source myself, my first question would be
are you sure it has to be deferred? In other words, is it possible that the
waiting for all threads to finish actually happens /within/ DestroyJavaVM()
?
 
T

Thomas Fritsch

Paul J. Lucas said:
I'm looking at the source code for the 'java' command-line tool
written in C. Near the bottom of main(), it calls the static
main() method of the main Java class via CallStaticVoidMethod().
It then detaches the current thread and destroys the JVM via
DestroyJavaVM().

The thing I don't understand is what if the Java main class's
main() spawns a thread, runs in that thread, whereas the
original thread returns from main() and dies. The call to
CallStaticVoidMethod() will then return and the C code will
continue, and then call DestroyJavaVM() effectively killing the
JVM out from under the still-running Java program.

This is what can happen in a Java Swing application where its
main() creates the AWT event thread and the application runs in
it, yet the original thread returns from main().

So how does this work? How is the call to DestroyJavaVM()
deferred?

- Paul
It is described in the JNI
spec.<http://java.sun.com/j2se/1.4.2/docs/guide/jni/spec/jniTOC.html>
Look for DestroyJavaVM there. It is inside the implementation of
DestroyJavaVM itself, where the waiting is done.
 
T

Thomas Hawtin

Thomas said:
Without actually looking at the source myself, my first question would be
are you sure it has to be deferred? In other words, is it possible that the
waiting for all threads to finish actually happens /within/ DestroyJavaVM()
?

I doubt it. I think the clue is that a Java thread isn't necessarily
equivalent to an OS thread. In the beginning were green threads that
were lightweight and all ran in the same OS thread. Not much cop for
multiprocessor machines, amongst other problems. Then Java threads used
OS threads. Then some JVMs use a number of OS threads, but can swap
lightweight Java threads in and out.

If a Java program continually creates and destroys Thread objects, a JVM
may be implemented such that Thread is just a light, throw-away wrapper.

When a JVM starts there isn't just the main thread. Not just the main
thread and the AWT EDT thread. There will be, depending on
implementation, threads for garbage collection, reference handling,
finalization, signal handling, etc. Come to think of it jstack will give
you a list:

"Attach Listener"
"AWT-Shutdown"
"AWT-XAWT"
"Java2D Disposer"
"Low Memory Detector"
"CompilerThread0"
"Signal Dispatcher"
"Finalizer"
"Reference Handler"
"VM Thread"
"VM Periodic Task Thread"

Anyway, what I'm getting to is that the thread that started the C main
function, needn't and probably isn't the one that starts the Java main
method. On some platforms you'd want to configure the thread in ways
that are only possible before it is started, and you don't have that
control over the originating native thread.

Tom Hawtin
 
T

Thomas G. Marshall

Thomas Hawtin coughed up:
I doubt it. I think the clue is that a Java thread isn't necessarily
equivalent to an OS thread. In the beginning were green threads that
were lightweight and all ran in the same OS thread. Not much cop for
multiprocessor machines, amongst other problems. Then Java threads
used OS threads. Then some JVMs use a number of OS threads, but can
swap lightweight Java threads in and out.

If a Java program continually creates and destroys Thread objects, a
JVM may be implemented such that Thread is just a light, throw-away
wrapper.
When a JVM starts there isn't just the main thread. Not just the main
thread and the AWT EDT thread. There will be, depending on
implementation, threads for garbage collection, reference handling,
finalization, signal handling, etc. Come to think of it jstack will
give you a list:

"Attach Listener"
"AWT-Shutdown"
"AWT-XAWT"
"Java2D Disposer"
"Low Memory Detector"
"CompilerThread0"
"Signal Dispatcher"
"Finalizer"
"Reference Handler"
"VM Thread"
"VM Periodic Task Thread"

Anyway, what I'm getting to is that the thread that started the C main
function, needn't and probably isn't the one that starts the Java main
method. On some platforms you'd want to configure the thread in ways
that are only possible before it is started, and you don't have that
control over the originating native thread.

Tom Hawtin

Yes, ok, and sure. But I'm not sure any of this addresses what I meant.

/Regardless/ of whether or not the java-thread is a made up concoction or a
real honest to got entry on the OS's wait queue, it can still be the case
that the C function in question:

DestroyJavaVM()

....is always called right after calling the C function CallStaticVoidMain(),
and it's job is to wait for all java non-daemon's to die, and then destroy
the JVM.
 
T

Thomas Hawtin

Thomas G. Marshall mopped up:
Thomas Hawtin coughed up:
I doubt it. [...]

Yes, ok, and sure. But I'm not sure any of this addresses what I meant.

/Regardless/ of whether or not the java-thread is a made up concoction or a
real honest to got entry on the OS's wait queue, it can still be the case
that the C function in question:

DestroyJavaVM()

...is always called right after calling the C function CallStaticVoidMain(),
and it's job is to wait for all java non-daemon's to die, and then destroy
the JVM.

Yup, after looking at the documentation my suspicions in this matter
appear to fall short of correctness.

Tom Hawtin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,817
Latest member
DicWeils

Latest Threads

Top