Java 线程运行
/**
* 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 */
}
}
}
Thread中的start()方法
注解很明确地说明,该方法让新创建的线程运行,java虚拟机会调用thread的run方法。调用start()的结果是会有两个线程在同时运行,当前线程是从start()方法的调用处返回,另一个线程执行他的run方法。永远不允许start一个线程两次,多次start将会报出"java.lang.IllegalThreadStateException”异常。尤其,一旦一个线程已经完成了执行,他将不会重启。
这个方法不会被由虚拟机创建/设置的主线程或者系统组线程唤起。将来,添加到这个方法里的功能都要被添加到虚拟机中。0状态相当于"NEW"状态。</br>
1.首先判断这个线程的状态是否是零,如果不是则报错。</br>
2.将这个线程加入到线程组中 group.add(this) 通知线程组这个线程即将被启动,所以这个线程可以被添加到线程组线程列表中,并且线程组没有启动的现场数需要减少。在线程初始化init中,“g.addUnstarted();”增加了线程组未启动的线程数,在这里需要将他减去。</br>
3.调用start0(),如果没有异常则started状态被置为true,否则将这个线程加入到线程组启动失败的列表中。</br>
group.threadStartFailed(this) 移除线程并且未启动线程数+1</br>
void threadStartFailed(Thread t) {
synchronized(this) {
remove(t);
nUnstartedThreads++;
}
}
start0()方法在Thread源码
private native void start0();
registerNatives.png
registerNatives()方法主要的作用就是注册一些本地方法供 Thread 类使用,如 start0(),stop0() 等等,可以说,所有操作本地线程的本地方法都是由它注册的。这个方法放在一个 static 语句块中,这就表明,当该类被加载到 JVM 中的时候,它就会被调用,进而注册相应的本地方法。
</br>
Java Thread:揭开Run方法被调用的真正面纱</br>
native方法 称为本地方法。在java源程序中以关键字“native”声明,不提供函数体。其实现使用C/C++语言在另外的文件中编写,编写的规则遵循Java本地接口的规范Java native Interface(简称JNI)。简而言就是Java中声明的可调用的使用C/C++实现的方法</br>
native关键字
标识符native可以与所有其它的java标识符连用,但是abstract除外。这是合理的,因为native暗示这些方法是有实现体的,只不过这些实现体是非java的,但是abstract却显然的指明这些方法无实现体.</p>
一个native method方法可以返回任何java类型,包括非基本类型,而且同样可以进行异常控制。这些方法的实现体可以制一个异常并且将其抛出,这一点与java的方法非常相似。当一个native method接收到一些非基本类型时如Object或一个整型数组时,这个方法可以访问这非些基本型的内部,但是这将使这个native方法依赖于你所访问的java类的实现。有一点要牢牢记住:我们可以在一个native method的本地实现中访问所有的java特性,但是这要依赖于你所访问的java特性的实现,而且这样做远远不如在java语言中使用那些特性方便和容易。</p>
native method的存在并不会对其他类调用这些本地方法产生任何影响,实际上调用这些方法的其他类甚至不知道它所调用的是一个本地方法。JVM将控制调用本地方法的所有细节。需要注意当我们将一个本地方法声明为final的情况。用java实现的方法体在被编译时可能会因为内联而产生效率上的提升。但是一个native final方法是否也能获得这样的好处却是值得怀疑的,但是这只是一个代码优化方面的问题,对功能实现没有影响。</p>
如果一个含有本地方法的类被继承,子类会继承这个本地方法并且可以用java语言重写这个方法(这个似乎看起来有些奇怪),同样的如果一个本地方法被final标识,它被继承后不能被重写。</p>
本地方法非常有用,因为它有效地扩充了JVM .事实上,我们所写的java代码已经用到了本地方法,在sun的java的并发(多线程)的机制实现中,许多与操作系统的接触点都用到了本地方法,这得java程序能够超越java运行时的界限。有了本地方法,java程序可以做任何应用层次的任务。</p>
synchronized关键字
start()方法用synchronized修饰,即这个方法就是同步方法,他锁定的是调用这个同步方法对象。</br>
Java的synchronized关键字:同步机制总结