线程基础概念和java中的线程-0823
java中的线程和操作系统的线程是什么关系
1.java线程的本质
-
start方法启动后,调用软方法run()
-
start()源码的线程控制原语
- start0();
- native方法,JNI方法,对应于一个c语言方法
- 怎么看这个方法,在github上下载open jdk方法
- 为什么下的是jdk11,编译jdk11必须要有jdk8的代码
- 底层是jvm.cpp
- jvm_startThread()
- pthread_create(),由glibC提供,四个参数
- pthread_t *thread:传出参数
- pthread_attr_t
- void(start routine)(void *)
- 是jvm内部写死的方法,会回调java线程中的run()方法
- void *arg:参数,非必须
- pthread_create(),由glibC提供,四个参数
- os_linux.cpp()
- Thread.c
- JNINativeMethod有一个数组,里面有一个start0方法
- JVM_StartThread()
- MutexLocker()
- jvm_startThread()
- start0();
-
怎么看open jdk代码
- 下载一个clion的idea
- 为什么下的是jdk11,编译jdk11必须要有jdk8的代码,下载11、12的代码
- idea中进行debug,配置选项
- debug argument :com.shadow.app.ThreadDemo
- 需要把自己编译的类放到虚拟机中的bin目录下
- debug过程中,会启动很多线程,所以跳过一些断点,才会跳到os_linux.cpp()中的pthread_create()是由自己编译的类实现的
-
aqs比sysnchronized的效率高
- aqs压根就没有调过c++的代码
-
启动过程
- Thread.start()
- native Thread.start0()
- JVM 实例化一个c++对象JavaThread(JVM_ENTRY–宏)
- 判断os,如果是linux系统,会调用pthread_create()
-
通过自己手写native中的start0方法,跳过上述步骤中的3
-
需要使用JNI
-
java文件
- System.loadLibrary(“EnjoyThreadNative”)
- EnjoyThreadNative需要与转换成.so名字中的命令中的Libxxx中的xxx对应
-
第一步编译,javah编译一个.h文件
-
javah在java9之后就没有了
-
java11之后javac xx.java
javac -h . xx.java(java11中间有一个点,要注意)
-
会多一个.h文件
-
-
第二步需要把上一步生成的.h文件中的方法名复制到自己的.c文件中
-
第三步把.c文件转换成.so文件
-
第四步需要把.so文件所在目录加到linux需要加载的资源目录中
-
-
答疑
1.java中的线程内容是跟操作系统中的线程对应的
2.怎么解决事务补偿
3.幂等解决方法(某一个方法有10行,运行了5行,在这里挂掉了,服务恢复后,不能重复前5行)
4.P类和R类