JVM inicia el método principal en un subproceso separado, es el subproceso principal del subproceso secundario, por eso no ve el subproceso secundario en la parte superior de la jerarquía de invocación.
Por lo tanto, en su caso, JVM creó un subproceso que inició su programa, que también amplía el subproceso.
Luego, en su método principal creó una nueva instancia de su clase, llamada start on it, esto iniciará un nuevo hilo que es hijo de thread iniciado por JVM para iniciar su programa.
Dado que el método principal es un punto de partida para un programa java independiente, es responsabilidad de JVM iniciarlo en un hilo separado, no debe escribir código para él.
Al iniciar un programa llamando al método principal, JVM no necesita que sea un subproceso o implementar Runnable, es un procedimiento estándar.
Descripción de Inside Java Virtual Machine
El método main() de la clase inicial de una aplicación sirve como el punto de partida para el hilo inicial de esa aplicación. El subproceso inicial puede, a su vez, desencadenar otros subprocesos.
Dentro de la máquina virtual Java, los subprocesos vienen en dos sabores: daemon y no demonio. Un subproceso de daemon suele ser un subproceso utilizado por la propia máquina virtual , como un subproceso que realiza la recolección de basura. La aplicación, sin embargo, puede marcar cualquier subproceso que cree como subprocesos de daemon. El hilo inicial de una aplicación - el que comienza en main() - es un hilo que no es daemon.
Una aplicación Java continúa ejecutando (la instancia de la máquina virtual sigue viviendo), siempre y cuando todos los hilos no demonio siguen siendo ejecución. Cuando todos los subprocesos no daemon de una aplicación Java finalicen, se cerrará la instancia de la máquina virtual. Si el administrador de seguridad lo permite, la aplicación también puede causar su propia desaparición invocando el método exit() de la clase Runtime o System.
La jerarquía de llamadas no se rige por usted sino que se rige por el planificador de subprocesos subyacente.
Así por ejemplo, si se me acaba el mismo código en mi máquina esta es la salida
Exception in thread "main" java.lang.RuntimeException: Exception from main thread
at TestThread.main(TestThread.java:6)
Exception in thread "Thread-1" java.lang.RuntimeException: Exception from child thread
at TestThread.run(TestThread.java:9)
at java.lang.Thread.run(Thread.java:662)
por lo que cuando se ejecutó tu ejemplo, planificador optan por dejar ir hilo hijo antes de principal.
Añadiendo a @JB Nizet, la forma en que se invocará un programa o cómo se implementará un ciclo de vida de hilo depende del sistema operativo y el hardware subyacentes, lo que varía y varía.
No hay detalles únicos de implementación que proporcionen una respuesta completa, cada implementación variará.
Solo para aclarar lo que está preguntando: ¿su expectativa es que 'main()' se invoque de manera diferente cuando su clase propietaria implemente 'Runnable'? (Porque no lo es) – cheeken