2016-08-29 5 views
-6
public class HelloRunnable implements Runnable { 

public void run() { 
    System.out.println("Hello from a thread!"); 
} 

public static void main(String args[]) { 
    (new Thread(new HelloRunnable())).start(); 
} } 

Согласно Java DocКакой метод вызывает run()?

Runnable Интерфейс определяет один метод, run, означало, чтобы содержать код выполняется в потоке. Объект Runnable передается конструктору Thread.

Итак, Когда мы запускаем HelloRunnable, кто вызывает метод внутреннего запуска? В Thread классе, метод start выглядит следующим образом:

public synchronized void start() { 
    if (threadStatus != 0) 
     throw new IllegalThreadStateException(); 
    group.add(this); 
    start0(); 
    if (stopBeforeStart) { 
     stop0(throwableFromStop); 
    } 
} 

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

+4

Как насчет метода 'start0', он вызывает метод' run'? Я имею в виду, что нет волшебства, верно? Если вы вызываете 'run', кто-то должен его называть :-) – dasblinkenlight

+0

что такое * threadstatus *? stopBeforeStart? –

+0

@dasblinkenlight start0() выглядит так: inline 'private native void Больше ... start0();' –

ответ

7

Указывается прямо в documentation of start:

виртуальная машина языка Ява вызывает run метод этого потока

Таким образом, это нативный код в start0 из виртуальной машины Java, который берет на себя вызова run во вновь созданной ветке. (Это не совсем неожиданное, поскольку запуск нити очень OS-специфичен и не могут быть реализованы в чистом Java.)

Примечания: start0 не вызывают run непосредственно. Вместо этого (на высоком уровне, игнорируя JVM-внутреннее управление), он инструктирует операционную систему создать новый поток и позволить этому потоку выполнить run.

Просто чтобы прояснить, вот краткое описание задействованных методов:

  • start функция высокого уровня, чтобы начать новый Thread.

  • start0 - это родной метод, который создает новую тему из операционной системы и отвечает за то, чтобы вызывать run.

  • run - это метод, определенный в ваших классах Runnable. Этот метод будет выполнен в новом потоке. Объект Thread в самой Java не имеет понятия о коде пользователя, который он должен выполнить. Это несет ответственность за связанный объект Runnable.

Таким образом, при вызове Thread.start(), то run метод Runnable будет автоматически вызывается.

Конечно, вы всегда можете вызвать run метод в явном виде: Runnable

HelloRunnable hr = new HelloRunnable(); 
hr.run(); 

Однако, это будет, конечно же, не быть выполнен в отдельном потоке, но блокировать выполнение.

+0

Затем, когда JVM входит в изображение, например, как JVM получает уведомление о том, что start() был вызван, и теперь пришло время вызвать метод run()? @martin –

+0

Хорошо, спасибо. (Просто любопытно). Можно ли вызвать run() (чистый код Java) из собственного кода? –

+1

Я замечаю, что вы осторожны, чтобы сказать, что 'start0'" заботится о вызове '' run() ', но вы можете быть более явным в том, что он не _call_' run() '. На самом деле 'run()' не вызывается из _anywhere_ в вызове 'start()'. Он вызывается в отдельном потоке. Это концепция, которую многие нообы испытывают затруднения. –