线程如何运行?

我在Threads.上看了一个小例子。为了创建Threads,我们可以通过实现Runnable接口或者通过扩展Thread来做两种方式。我使用第一种方式

 package test; public class test implements Runnable{ public static void main(String args[]) { test t=new test(); t.run();Thread th=Thread.currentThread(); th.start(); } @Override public void run() { // TODO Auto-generated method stub System.out.println("hi"); } } 

我怀疑是什么时候我们打电话给th.start(); 然后调用run()我想知道如何。我在内部认为start()可能正在调用run()所以我查看了Thread类的文档

以下是Thread类中的start()声明

 public synchronized void start() { /** * This method is not invoked for the main method thread or "system" * group threads created/set up by the VM. Any new functionality added * to this method in the future may have to also be added to the VM. * * A zero status value corresponds to state "NEW". */ if (threadStatus != 0) throw new IllegalThreadStateException(); /* Notify the group that this thread is about to be started * so that it can be added to the group's list of threads * and the group's unstarted count can be decremented. */ group.add(this); boolean started = false; try { start0(); started = true; } finally { try { if (!started) { group.threadStartFailed(this); } } catch (Throwable ignore) { /* do nothing. If start0 threw a Throwable then it will be passed up the call stack */ } } } 

正如你在start()看到的那样, run()没有被调用,但是当我们调用th.start()会自动覆盖run()被调用。任何人都可以在这里th.start()一些亮点

在新线程上调用run方法的机制是extralinguistic :它不能用Java代码表示。 这是start方法中的关键行:

  start0(); 

start0是一个本机方法,其调用将:

  • 导致创建新的本机执行线程;
  • 导致在该线程上调用run方法。
  Thread th=Thread.currentThread(); th.start();// its call run method automatically if you call direct run method with class object than its treat as a normal method not thread method 

Thread类的start()方法用于启动新创建的线程。 它执行以下任务:新线程启动(使用新的callstack)。 线程从New状态移动到Runnable状态。 当线程有机会执行时,它的目标run()方法将运行。

它不应该调用run方法。 如果是,它将在同一个运行的线程中执行。

就像程序在类的main方法中启动一样,新的线程在类的run方法中启动。 您必须查看本机代码才能找到它。

您可以在Thread.start()方法的文档中找到答案。 http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#start()

内部启动方法调用run方法。

简单的实验可以揭示事实。 调用Thread.start()和Thread.run(),在run方法中保留一条打印消息语句。 此消息将显示两次,因为run方法被调用两次。

在问题代码中查看此语句。 在调用start0之前,启动标志为false,调用start0()函数后,starrted标志为true。 这意味着使用start0()调用run方法。

 boolean started = false; try { start0(); started = true; } 

确切地说,start0方法创建了新的thred来执行run方法,并返回当前线程。

来自oracle官方文档

“public void start()导致此线程开始执行; Java虚拟机调用此线程的run方法。结果是两个线程并发运行:当前线程(从调用start方法返回)和另一个线程(执行其run方法)。

不止一次启动线程永远不合法。 特别是,一旦完成执行,线程可能无法重新启动。

抛出:IllegalThreadStateException – 如果线程已经启动。 另请参见:run(),stop()“