Как работает метод Java run ()?
===============================

Многопоточность в Java выполняется путем определения run () и вызова start ().

Запустите делегаты нативному методу, который запускает поток через подпрограммы операционной системы, и run () вызывается из этого вновь порожденного потока.

При запуске автономного приложения автоматически создается главный поток для выполнения функции main ().

Теперь рассмотрим этот код -

Это вывод -

Если метод main () запускается через поток, почему функция run () не отображается в верхней части иерархии вызовов?

Как основной поток может быть создан без реализации Runnable?

 но предположил бы, что JVM создает основной поток для запуска метода main, но запускает этот основной поток, вызывая нативный код напрямую, без прохождения классических классов и методов Java для начать поток.



 это семантический аргумент, но поток и процесс не являются синонимами.

Процесс запускается операционной системой и имеет собственные закрытые кодовые страницы (скомпилированный набор кода). Поток запускается из внутренних компонентов программы и первоначально разделяет кодовые страницы своих родителей (скомпилированный набор кода).

То, что JVM внутренне использует поток для запуска метода main, - это деталь реализации среды, но не представление языка Java. Если поток должен был сообщить в`main` В кадрах стека архитектура обратной ссылки на позицию исходного кода была бы невозможна, потому что этот основной обслуживающий поток не имел бы модуля компиляции (он является внутренним для JVM).



 это родительский поток дочернего потока, поэтому вы не видите дочерний поток в верхней части иерархии вызовов.

Так что в вашем случае JVM создал поток, запустил вашу программу, которая также расширяет поток.

Затем в вашем основном методе вы создали новый экземпляр вашего класса, который называется start on it, это запустит новый поток, который является дочерним по отношению к потоку, запущенному JVM для запуска вашей программы.

Поскольку метод main является отправной точкой для автономной Java-программы, JVM отвечает за его запуск в отдельном потоке, поэтому вы не пишете для него код.

Хотя запуск программы с помощью вызова основного метода JVM не требует, чтобы он был потоком или реализовал Runnable, это стандартная процедура.

Описание от[Внутри виртуальной машины Java](http://www.artima.com/insidejvm/ed2/jvm.html)

The main() method of an application's initial class serves as the
 starting point for that application's initial thread. The initial
 thread can in turn fire off other threads.

Inside the Java virtual machine, threads come in two flavors: daemon
 and non- daemon. A daemon thread is ordinarily a thread used by the
 virtual machine itself, such as a thread that performs garbage
 collection. The application, however, can mark any threads it creates
 as daemon threads. The initial thread of an application--the one that
 begins at main()--is a non- daemon thread.

A Java application continues to execute (the virtual machine instance
 continues to live) as long as any non-daemon threads are still
 running. When all non-daemon threads of a Java application terminate,
 the virtual machine instance will exit. If permitted by the security
 manager, the application can also cause its own demise by invoking the
 exit() method of class Runtime or System.

Иерархия вызовов не зависит от вас, а от основного планировщика потоков.

Так, например, если я запускаю тот же код на моей машине, это вывод

поэтому, когда вы запустили свой пример, планировщик решил сначала пустить дочерний поток перед главным.

Добавление в @JB Nizet того, как будет вызываться программа или как будет реализован жизненный цикл потока, зависит от базовой ОС и аппаратного обеспечения, которое будет изменяться.

Никакие подробности реализации не дадут полного ответа, каждая реализация будет отличаться.



t run() show up at the top of invocation hierarchy?

Как уже упоминали другие, это потому, что "основной" Нить особенная. Не запускается через стандарт`Thread` механизмы классов, но вместо этого с помощью загрузочного кода Java.`public static void main(String[] args)` всегда запускается основным потоком из нативного кода.

Другое объяснение состоит в том, что на самом деле может быть`run()` метод, но то, как они строят стековый фрейм, скрывает его специально, чтобы не сбить с толку пользователя. Например, так как вы делаете`new Thread(new Test())` тогда ваш`Test` класс на самом деле`target` поле внутри`Thread`, Когда фон`Thread` запускается, то это на самом деле вызывает`Thread.run()` который имеет код:

Но мы никогда не видим`Thread.run()` метод в стеке, хотя кажется, что он должен быть там.`run()` методwould быть в стеке, если пользователь переопределил его в`Thread` суперкласс. Он может быть удален JDK для улучшения вывода стекового кадра.

Multi-threading in Java is done by defining run() and invoking start().

Это правильно, но для потомков я подумал, что важно понять, что у вашего кода есть проблема. Ваш`Test` класс долженnot расширяться`Thread` но вместо этого следует осуществлять`Runnable`, Это работает потому что`Thread` инвентарь`Runnable`.

Либо вы должны реализовать`Runnable` и измените свой код на что-то вроде этого:

Или вы все еще расширяете`Thread` и измените способ запуска вашей темы на что-то вроде следующего. Выше`Runnable` шаблон рекомендуется, так как это позволяет вашему`Test` поток, чтобы расширить другой класс, если это необходимо.

Почему это важно? Вы текущий код на самом деле создает 2`Thread` объекты, но только один из них`start()`Эд и работает в качестве фона`Thread`, Вы можете получить что-то вроде следующей ошибки: