线程的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的设计,其实就是一个典型的模板模式,也就是父类编写算法结构代码,具体的逻辑实现由子类去完成。
获取实时信息,关注公众号:『编程之艺术』,二维码: