java 线程模型

执行流程


  • 我们从一个简单的启动线程开始看
public static void main(String[] args){
  new Thread(){
   @Override
   public void run() {
    super.run();
   }
  }.start();
}


 这是一个最基础的线程启动方法,我们点进去看下



我们看下上面的这部分代码


  • 第一步校验线程的状态,我们知道线程的状态从new->running,他这新的线程标识为0,也就是说非0的线程不启动,抛出异常
  • group.add 将线程加入到group组中,这个group组是呈递减的
  • 在下面的核心方法 try{}中的start方法
  • -start方法我们从上图也能看到最终执行了一个Native方法 start0,也就是说他是JDK提供的


so,我们来看JDK源码中的对这个方法的具体实现


JDK 中的实现


打开JDK源码,jdk/src/share/native/java/lang/Thread.c,找到start0

我们知道与之对应的在JVM中的方法为StartThread,再找到JVM中的这个方法


相应的代码我们在hotspot下,在这个路径 jdk/src/share/native/java/lang/Thread.c

我们看下这个方法

核心就是这一段


创建了一个javaThread的对象



我们看到这个对象创建经过初始化后,通过 os::create_thread创建



所谓的OS就是不同系统下创建的方式,我们看到有Linux,windows等,我们来看Linux


这个文件里有个pthread_create(),查看下Linux的文档


The pthread_create() function starts a new thread in the calling process. The new thread starts execution by invoking start_routine(); arg is passed as the sole argument of start_routine().


The new thread terminates in one of the following ways


这是唯一创建线程的一个方法,OK。看到这我们也就明白了,每次我们start一个线程,最终我们都会在操作系统中创建一个线程


总结


从上面的源码的创建流程我们看到,最终用户态线程和内核态的关系是1:1。线程有自己的独立的栈,调度也依赖操作系统。


从前几篇文章我们分析了操作系统的线程模型后,我们知道系统调用的消耗是异常消耗资源的。在早期计算机的发展过程里是没有对多线程提供支持的。


Linux 中进程与进程之间有各自独立的数据空间(堆和栈,非亲戚进程还是独立的程序代码),进程本身占用的资源以及它们之间的交互都相对重量级。而线程的概念可以简单的认为是,相对独立的一个执行流,同时它们之间可以共享应用程序的大部分数据结构

暂无评论