线程如何运行?
我在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()“