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

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

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

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

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

public class Test extends Thread {
    public static void main(String[] args) throws Exception {
        new Thread(new Test()).start();
        throw new RuntimeException("Exception from main thread");
    }
    public void run() {
        throw new RuntimeException("Exception from child thread");
    }
}

Это вывод -

java.lang.RuntimeException: Exception from child thread
    at com.Test.run(Test.java:11)
    at java.lang.Thread.run(Thread.java:662)
java.lang.RuntimeException: Exception from main thread
    at com.Test.main(Test.java:8)

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

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

 cheeken26 мая 2012 г., 08:16
Просто чтобы уточнить, что вы спрашиваете: это ваше ожидание, чтоmain() вызывается по-разному, когда его собственный класс реализуетRunnable? (Потому что это не так.)

Ответы на вопрос(4)

Решение Вопроса

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

 26 мая 2012 г., 08:42
точно в цель :) +1

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

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

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

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

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

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

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

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

Описание отВнутри виртуальной машины Java

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.

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

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

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)

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

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

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

 26 мая 2012 г., 07:54
прочитать обновление
 26 мая 2012 г., 09:51
JVM делает саму реализацию. Вы не можете «дублировать» это или что-либо еще, это просто «волшебство».
 Kshitiz Sharma26 мая 2012 г., 08:09
Этот пункт объясняет потоки демона и завершение потока. Не мой вопрос & gt; & gt; это стандартная процедура & quot; Как осуществляется стандартная процедура?

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() который имеет код:

public void run() {
    if (target != null) {
        target.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 и измените свой код на что-то вроде этого:

public class Test implements Runnable {
    public static void main(String[] args) throws Exception {
        new Thread(new Test()).start();
        throw new RuntimeException("Exception from main thread");
    }
    public void run() {
        throw new RuntimeException("Exception from child thread");
    }
}

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

public class Test extends Thread {
    public static void main(String[] args) throws Exception {
        new Test().start();
        throw new RuntimeException("Exception from main thread");
    }
    @Override
    public void run() {
        throw new RuntimeException("Exception from child thread");
    }
}

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

public class Test extends Thread {
    public static void main(String[] args) throws Exception {
        Test test = new Test(); 
        new Thread(test).start();
        // this is not interrupting the background thread
        test.interrupt();

Ваш ответ на вопрос