/**** 线程创建跟踪*/
public class ThreadCreate {public static void main(String[] args) {new Thread(()->{System.out.println(1);}).start();}
}

在以上代码中,线程并非在new的时候就被创建,而是执行了start()方法之后才被创建。
继续往下跟踪,进入start()方法所在类查看源码,找到关键的一行代码,
start0(),这个方法是创建线程的方法,继续往下点。
会发现start0native方法,简单科普一下,被native修饰的方法代表此方法由其他语言的接口提供,比如C或C++,此时我们再点,发现点不进去了。
再往下我们需要下载OpenJDK来查看源代码,点此下载最新版本,
找到和Thread相关的Thread.c文件后,用任意方法查看此文件,找到start0()方法,具体如下
在上图可以看出,这里对start0()方法做了一个1对1的映射,映射到了JVM_StartThread()这个方法,那么我们继续在OpenJDK中寻找这个方法。
到这里之后可以看到这里又调用了一个C++的方法,我们继续往下找这个JavaThread(&thread_entry, sz)

一如既往,继续找os::create_thread(this, thr_type, stack_sz)

bool os::create_thread(Thread* thread, ThreadType thr_type,size_t req_stack_size) {assert(thread->osthread() == NULL, "caller responsible");// Allocate the OSThread objectOSThread* osthread = new OSThread(NULL, NULL);if (osthread == NULL) {return false;}// set the correct thread stateosthread->set_thread_type(thr_type);// Initial state is ALLOCATED but not INITIALIZEDosthread->set_state(ALLOCATED);thread->set_osthread(osthread);// init thread attributespthread_attr_t attr;pthread_attr_init(&attr);pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);// Calculate stack size if it's not specified by caller.size_t stack_size = os::Posix::get_initial_stack_size(thr_type, req_stack_size);// In glibc versions prior to 2.7 the guard size mechanism// is not implemented properly. The posix standard requires adding// the size of the guard pages to the stack size, instead Linux// takes the space out of 'stacksize'. Thus we adapt the requested// stack_size by the size of the guard pages to mimick proper// behaviour. However, be careful not to end up with a size// of zero due to overflow. Don't add the guard page in that case.size_t guard_size = os::Linux::default_guard_size(thr_type);// Configure glibc guard page. Must happen before calling// get_static_tls_area_size(), which uses the guard_size.pthread_attr_setguardsize(&attr, guard_size);size_t stack_adjust_size = 0;if (AdjustStackSizeForTLS) {// Adjust the stack_size for on-stack TLS - see get_static_tls_area_size().stack_adjust_size += get_static_tls_area_size(&attr);} else {stack_adjust_size += guard_size;}stack_adjust_size = align_up(stack_adjust_size, os::vm_page_size());if (stack_size <= SIZE_MAX - stack_adjust_size) {stack_size += stack_adjust_size;}assert(is_aligned(stack_size, os::vm_page_size()), "stack_size not aligned");int status = pthread_attr_setstacksize(&attr, stack_size);assert_status(status == 0, status, "pthread_attr_setstacksize");ThreadState state;{pthread_t tid;int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);char buf[64];if (ret == 0) {log_info(os, thread)("Thread started (pthread id: " UINTX_FORMAT ", attributes: %s). ",(uintx) tid, os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));} else {log_warning(os, thread)("Failed to start thread - pthread_create failed (%s) for attributes: %s.",os::errno_name(ret), os::Posix::describe_pthread_attr(buf, sizeof(buf), &attr));// Log some OS information which might explain why creating the thread failed.log_info(os, thread)("Number of threads approx. running in the VM: %d", Threads::number_of_threads());LogStream st(Log(os, thread)::info());os::Posix::print_rlimit_info(&st);os::print_memory_info(&st);os::Linux::print_proc_sys_info(&st);os::Linux::print_container_info(&st);}pthread_attr_destroy(&attr);if (ret != 0) {// Need to clean up stuff we've allocated so farthread->set_osthread(NULL);delete osthread;return false;}// Store pthread info into the OSThreadosthread->set_pthread_id(tid);// Wait until child thread is either initialized or aborted{Monitor* sync_with_child = osthread->startThread_lock();MutexLocker ml(sync_with_child, Mutex::_no_safepoint_check_flag);while ((state = osthread->get_state()) == ALLOCATED) {sync_with_child->wait_without_safepoint_check();}}}// Aborted due to thread limit being reachedif (state == ZOMBIE) {thread->set_osthread(NULL);delete osthread;return false;}// The thread is returned suspended (in state INITIALIZED),// and is started higher up in the call chainassert(state == INITIALIZED, "race condition");return true;
}
int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);

关键代码:int ret = pthread_create(&tid, &attr, (void* (*)(void*)) thread_native_entry, thread);
最终得证,执行start0方法才会调用系统内核的pthread_create()方法创建一个系统级别的线程。

最后更新于2021年1月5日早上5点
原创不易,如果该文章对你有所帮助,望左上角点击关注~如有任何技术相关问题,可通过评论联系我讨论,我会在力所能及之内进行相应回复以及开单章解决该问题.

该文章如有任何错误请在评论中指出,感激不尽,转载请附出处!
个人博客首页:https://blog.csdn.net/yjrguxing ——您的每个关注和评论都对我意义重大

通过跟踪源码证明在Java中通过执行Start()方法创建线程相关推荐

  1. java中arraycopy的用法_[jdk源码阅读系列]Java中System.arraycopy()的用法

    本文转载,原文链接: 3分钟了解Java中System.arraycopy的用法 - 伊万夫斯基 - 博客园  https://www.cnblogs.com/benjieqiang/p/114288 ...

  2. 【一起读源码】1. Java 中元组 Tuple

    1.1 问题描述 使用 Java 做数据分析.机器学习的时候,常常需要对批量的数据进行处理,如果需要处理的数据的维度不超过10时,可以考虑使用 org.javatuples 提供的 Tuple 类工具 ...

  3. 动图 + 源码,演示 Java 中常用数据结构执行过程及原理

    最近在整理数据结构方面的知识, 系统化看了下Java中常用数据结构, 突发奇想用动画来绘制数据流转过程. 主要基于jdk8, 可能会有些特性与jdk7之前不相同, 例如LinkedList Linke ...

  4. 数据结构中缀表达式转后缀表达式与后缀表达式的求值实训报告_动图+源码,演示 Java 中常用数据结构执行过程及原理...

    程序员的成长之路互联网/程序员/成长/职场 关注 阅读本文大概需要 3.7 分钟. 作者:大道方圆cnblogs.com/xdecode/p/9321848.html 最近在整理数据结构方面的知识, ...

  5. 动图+源码,演示 Java 中常用数据结构执行过程及原理

    程序员的成长之路 互联网/程序员/成长/职场 关注 阅读本文大概需要 3.7 分钟. 作者:大道方圆 cnblogs.com/xdecode/p/9321848.html 最近在整理数据结构方面的知识 ...

  6. 从源码出发:JAVA中对象的比较

    ✨前言✨

  7. Java多线程详解(如何创建线程)

    嗨喽-小伙伴们我们又见面了, 前面一章,我们了解了线程的基本概念,从这一章,我们开始学习如何创建一个线程.总的说来,在java中,有四种创建线程的方式: 1. 继承Thread类 2. 实现Runna ...

  8. java中Mark接口_JVM源码分析之Java对象头实现

    原标题:JVM源码分析之Java对象头实现 原创申明:本文由公众号[猿灯塔]原创,转载请说明出处标注 "365篇原创计划"第十一篇. 今天呢!灯塔君跟大家讲: JVM源码分析之Ja ...

  9. 【java集合框架源码剖析系列】java源码剖析之java集合中的折半插入排序算法

    注:关于排序算法,博主写过[数据结构排序算法系列]数据结构八大排序算法,基本上把所有的排序算法都详细的讲解过,而之所以单独将java集合中的排序算法拿出来讲解,是因为在阿里巴巴内推面试的时候面试官问过 ...

最新文章

  1. 令AI费解的图像层出不穷 计算机视觉远未达到完美
  2. 能说明白为啥三次握手的文章节选
  3. Python写入到csv文件存在空行的解决方法
  4. tddebug怎么读取asm文件_如何利用 ASM 实现既有方法的增强?
  5. Redis 和 Memcached 的区别
  6. centos 7 Chrony 集群同步时间
  7. python获取已打开网页的html,【已解决】Python的BeautifulSoup去实现提取带tag的HTML网页主体内容...
  8. parrot linux 安装grub,parrotsec 和 kali安装系统的时候出现“executing grub-install dummy”的解决方案...
  9. 在git的Bash下进行复制粘贴
  10. Bom Shanka Machines psymmetrix Delay for Mac(音频延迟效果器)
  11. hdu 1864 01背包
  12. python 表格模块 prettyTable 简单使用
  13. python实现从二维矩阵左上角到右下角的出路数寻找
  14. 5 EDA技术实用教程【基本语句2】
  15. java IO流:字节流、字符流
  16. 流量宝刷流量怎么操作不会被搜索引擎惩罚
  17. 读书笔记:学习C语言必须读的第二本书
  18. HTML5代码雨程序
  19. 华硕 X542UQ REV:2.1
  20. EMM系列1:EMM和ECM状态

热门文章

  1. 解决Ubuntu18.04 / 16.04和Win10双系统系统时间时间不同步
  2. 电脑连上网却无法使用浏览器,显示远程计算机或设备将不接受连接的解决办法
  3. JAVA从零开始开发区块链技术
  4. Android允许应用具有安装权限
  5. bd-rate的计算
  6. 禅道 10.0.alpha 版本发布,全新的界面和交互体验
  7. 爱奇艺体育获5亿元战略融资 ,IDG资本、汇盈博润领投
  8. Android 学习资料收集 1
  9. PTC Creo 5.0.2.0 + HelpCenter Win64 中文破解版
  10. 银行家算法的实验报告