线程的start方法解析
Thread是学习我们学习多线程接触到的第一个有关多线程的类,相信每一个学习过或者了解过Java多线程的小伙伴都知道Thread类。这次分享主要对Thread的start方法进行讲解。
相信大家都知道,start方法是启动一个线程,并且该线程进入了可执行状态。在实际的编码中,我们是重写run()方法,调用start()方法启动线程,那么run()和start()方法有什么联系呢?下面我们就详细说说。
一、源码分析
首先我们查看start的源码,如下:
/**
* 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()方法是非常简单的,如果从上面单独看上面源码是看不出任何端倪的,不过我们可以看出来Thread被创建之后,threadStatus这个内部属性的值是0 。在上面源码中,最核心的部分就是start0();这个本地方法,也就是我们经常能在其他博文中看到的JNI方法,所谓JNI方法其实没有那么高大上,其实JNI就是Java平台用于和本地C代码进行互操作的API,JNI不支持Java类和 C++类之间的任何映射机制,这里只是简单的提一句。为什么说start0();是最核心的部分呢?看下图:
那么我们重写的run方法是何时被调用的呢?可以看start方法的注释,如下图:

Causes this thread to begin execution; the Java Virtual Machine calls the <code>run</code> method of this thread.
这段注释是说:在开始执行这个线程时,JVM就会调用run方法,也就是说run方法就是被JNI方法start0调用的。
通过源码总结要点:
-
Thread被构建后的NEW状态下,threadStatus这个内部属性值为0;
-
不能两次启动Thread,不然就会出现IllegalThreadStateException异常;
-
group.threadStartFailed(this);可以看出线程启动后将会被加入到一个ThreadGroup中;
-
一个线程生命周期到了TERMINATED状态,是不允许调用start方法的。
总结:jdk对start和run的设计,其实就是一个典型的模板模式,也就是父类编写算法结构代码,具体的逻辑实现由子类去完成。
获取实时信息,关注公众号:『编程之艺术』,二维码:


浙公网安备 33010602011771号