Java多线程——线程启动函数start()源码解析
无论用哪种方式实现多线程,最终究其根源都是在调用Thread类的start()方法。(详情请参考:Java多线程的四种实现方式),而此时就有一个疑问了,若要实现多线程需要覆写其run()方法,而为什么要使用start()启动线程而不直接调用run()方法?
/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* <p>
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the
* <code>start</code> method) and the other thread (which executes its
* <code>run</code> method).
* <p>
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*
* @exception IllegalThreadStateException if the thread was already
* started.
* @see #run()
* @see #stop()
*/
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()使得该线程开始执行,Java虚拟机调用这个线程的run()方法,结果是两个线程会并发的运行
:当前线程(调用start()方法的"主线程")与另一个线程(执行其run方法)
/**
* A zero status value corresponds to state "NEW".
*/
if (threadStatus != 0)
throw new IllegalThreadStateException();
这段代码说明,IllegalThreadStateException这个异常的产生是由于重复的启动线程导致的。因此,每个线程对象只能启动一次
。
private native void start0();
很明显这是一个只声明而未实现的方法,native表示调用本机的原⽣系统函数
,native 方法往往意味着这个方法无法使用平台无关的手段来实现。所以,还是那句话,实际上线程的实现与 Java 无关
,由平台所决定,Java 所做的是将 Thread 对象映射到操作系统所提供的线程上面去,对外提供统一的操作接口
,向程序员隐藏了底层的细节,使程序员感觉在哪个平台上编写的有关于线程的代码都是一样的。这也是 Java 这门语言诞生之初的核心思想,一处编译,到处运行,只面向虚拟机,实现所谓的平台无关性,而这个平台无关性就是由虚拟机为我们提供的。
具体有关底层如何调用,请参考JAVA线程创建底层流程。
1、start()方法的具体流程:start(判断当前线程是不是首次创建,Java方法)->调用start0()方法(JVM)->通过JVM进行资源调度,系统分配->回调run()方法(Java方法)执行线程的具体操作任务。