一:Thread源码分析
分析下面源码可知:java的Thread是调用start()就绪一个线程,而start底层实则调用了native
start0(),被Native关键字声明的方法说明该方法不是以Java语言实现的,而是以本地语言实现的(eg:C++/C)。Java无法直接访问到操作系统底层如硬件系统,为此 Java提供了JNI(Java Native Interface)
来实现对于底层的访问。
小结:1、start()开始创建一个实质线程(不是指线程对象,而是OS中的线程),所以Java的线程和操作系统线程是一一对应的。
2、JNI(Java Native Interface)调用属于线程私有,用于本地方法的运行,可以理解成一个native方法就相当于是一个java调用非java代码的接口。
二:手写线程模拟调用
1、第一步:写一段java代码
1)使用 static静态加载的方法加载进来将要调用的库,名字即系统加载其他的语言的函数;
2)包含一个native的方法;
3)java的Thread是调用start(),假设我们手写的将来是调用start1()让它开启一个线程(名字随意起);
2、第二步:准备一个.c文件
1)将第一步写的java文件上传到linux,使用javah命令(jdk1.9后应该是javac -h . ) 后面跟类的全路径,生成一个头文件.h文件。
javac -h . com/xx/xx/EnjoyThread.java
下面是生成的.h文件,文件名为com_shadow_app_EnjoyThread.h
注意:jni.h头文件及目录
2)准备一个tnew.c文件:
3)将上一步.h文件中的名字Java_com_shadow_app_EnjoyThread_start1替换.c文件中中我们第一次随便写的那个名字start1(),并加入JNI语法的东西,修改后的.c文件:
注:<>与“”的区别,<>是导入外部的头文件,“”是导入自己的头文件
3、生成so文件
将改好的.c文件上传linux,用如下命令生成so文件(能被加载的库文件):
so的文件名叫做libEnjoyThread.so
-I后边的是jni.h的路径,一般在jdk…include中
至此java还是加载不到这几个so库的 ,还需要加其加到java的libarary库,如下命令:
(Windows环境下,所以用的是一 个.dll文件,如果在Linux环境下的话,用的是一个.so文件)