一、java线程的介绍:
在java的开发过程中,很多铁子对于java线程肯定不感到陌生,作为java里面重要的组成部分,这里就从如何创建一个线程给大家进行分析;
二、相关知识引入:
之前我了解过,java的线程其实是映射到操作系统的内核线程上的 ,所以Java线程基本上也就是操作系统在进行管理;大家都知道java语言内置了多线程技术,说到底其实就是java语言通过了一些操作请求了操作系统从而分配了创建线程的一些资源;
那么具体的是如何进行操作呢?
三、文件准备
在我们这里的分析过程中会涉及到一些java源代码openJDK文件中的代码展示,所以需要大家准备一下openJDK,我这里将其分享出来
链接: https://pan.baidu.com/s/1No90NPoMI9PF7hIHk3nAUg?pwd=9qzu 提取码: 9qzu
四、源码分析
1、在我们java代码中创建线程主要是用的Thread类,所以第一步我们先创建一个Thread类对象;
public static void main(String[] args) {
//创建线程并调用start()方法
new Thread().start();
}
2、我们创建了一个Thread类,自然会调用Thread类里面的构造方法,这个时候我们按住Thread来到Thread.java类里面,可以看到进入到了这个类里面
3、关键的不是这个构造方法,我们来到类名这儿,可以看到有个静态方法,这个静态方法在对象创建的时候也会执行,然后会调用里面的registerNatives()方法,而这个方法就在他头上
这里给大家说创建对象主要是分享静态方法里面会去调用registerNatives方法,他会去进行一个执行,大家记住这个点就好了;
4、这个时候我们就来到 registerNatives()静态方法这儿,可以看到里面有一个native这个单词修饰,这个在之前可能大家可能都不知道;
我这里给大家做一个解释,这个native在java里面的一个含义:有native关键字修饰的方法,表示通过jvm调用底层操作系统的函数方法;就是去调用c语言的方法
综上,所以在这个registerNativs方法中,java的任务就完成了,java就是让jvm去调用c相关的方法进行一个执行;
5、那我们就应该去找到c相关文件中的registerNativs方法,看看他到底是什么意思,于是这个时候打开openJKD文件,找到openjdk-8u40-src-b25-10_feb_2015\openjdk\jdk\src\share\native\java\lang\Thread.c文件,打开看到里面的内容
这里面是定义了一个数组,数组中存放的为JNINativeMethod类型的结构体变量,JNINativeMethod这种类型如下,这个类型的定位是在jni.h文件中:
typedef struct {
char *name;
char *signature;
void *fnPtr;
} JNINativeMethod;
JNINativeMethod主要是进行一个jni方法的映射关系,将native方法【可以理解成java方的名词】和真正的实现方法【c语言里面的方法名】进行绑定。
6、当映射被绑定后,java里面就能通过一些jni方法去找到c语言里面对应的真实方法,然后java执行start()后,会去Thread里面执行start0()方法
7、所以这个时候,就会通过jvm去找映射关系,在映射里面start0对应的是JVM_StartThread方法,所以就来到了第二个关键文件,openjdk-8u40-src-b25-10_feb_2015\openjdk\hotspot\src\share\vm\prims\jvm.cpp,这个文件里面存放了JVM_StartThread这个方法做的事情,
8、往下面走,来到2851行代码,会发现一个new的代码,他这个里面做的功能是创建一个Java线程对应的内核线程,主要就是靠这个构造方法创建一个对象然后放到native_thread变量中
9、接着,来到2884行代码里面,可以看到调用了Thread::start(native_thread)这个方法,他就是带着刚刚创建好的变量然后进行一个启动操作,所以我们需要找到Thread::start(native_thread),他这里面做了什么事情
10、所以我们继续来到第三个关键文件,openjdk-8u40-src-b25-10_feb_2015\openjdk\hotspot\src\share\vm\runtime\Thread.cpp,然后根据上面的Thread::start(native_thread)直接搜一把就可以找到这个方法
11、上面的方法中,前面几行简单,来到464行,里面有一个os::start_thread(thread);这个里面有个os,他代表操作系统,意思就是让操作系统去执行start_thread(thread)方法,便开始真正的启动Java线程对应的内核线程,自此一个大概流程就走完了,到这里java线程就运行起来了,有些小细节没有说,更多的细节可以进一步了解。
五、名词解析:
1、native关键字修饰的方法,表示通过jvm调用底层操作系统的函数方法
2、JNI=java native interface
3、线程其实和java没多大关系,只是java能通过一些接口然后最终让操作系统为其创建线程
六、总结
java中创建线程并执行首先是jvm通过JNI方式加载好映射文件,然后通过start0这个名词找到对应的c文件里面的JVM_StartThread方法,然后在jvm.cpp文件中找到JVM_StartThread方法执行流程,然后通过os创建线程并最终执行
的c文件里面的JVM_StartThread方法,然后在jvm.cpp文件中找到JVM_StartThread方法执行流程,然后通过os创建线程并最终执行