Java--深入JDK和hotspot底层源码剖析Thread的run()、start()方法执行过程_jdk的源码hotspot跟jdk是分开的

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新网络安全全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上网络安全知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

需要这份系统化资料的朋友,可以点击这里获取

进入正文~


学习目录

一、代码测试

执行Thread的run()、start()方法的测试代码如下:

public class MyThread {
    public static void print() {
        System.out.println("print...");
        System.out.println(Thread.currentThread().getName());
    }

    public static void main(String[] args) throws InterruptedException {
        Thread thread1 = new Thread() {
            @Override
            public void run() {
                System.out.println("执行print()方法的线程是:" + Thread.currentThread().getName());
                print();
            }
        };
        System.out.println("一、调用run()方法的线程是:" + Thread.currentThread().getName());
        thread1.run();

        Thread.sleep(1000);

        System.out.println("二、调用start()方法的线程是:" + Thread.currentThread().getName());
        thread1.start();
    }
}

测试结果:

一、调用run()方法的线程是:main
执行print()方法的线程是:main
print...
main
二、调用start()方法的线程是:main
执行print()方法的线程是:Thread-0
print...
Thread-0


简单总结:

  • run()方法调用和执行重写的代码块都是由main主线程来完成的;
  • start()方法调用是有main()主线程来调用,但是重写的代码块是由非main主线程来执行的。

二、源码分析

2.1 run()方法

通过线程调用run()方法,这个其实很简单,比如前面测试代码执行run方法:

thread1.run();

Ctrl + 鼠标左键,进入到java.lang.Threadrun()方法的源码:

    @Override
    public void run() {
        if (target != null) {
            target.run();
        }
    }

再Ctrl + Alt + 鼠标左键,定位前面测试类MyThread中重写的run()方法
在这里插入图片描述
可以发现,直接就调用到重写的run()方法了,并且,你可以重复调用多次,而且每一次都是由main主线程调用run()方法,然后非main主线程,执行run()方法代码块
在这里插入图片描述
虽然run()方法也可以直接执行到重写的代码块,不过实际当中,按规范来说,不会直接调用run()执行,而是通过start()方法来开启线程,start()方法底层会判断线程的状态,开启线程,最终调用run()方法并结束线程状态,往后了解。

2.2 start()方法

Oracle JDK源码stat()方法:

public class Thread implements Runnable {
   ...
   private ThreadGroup group;
   private volatile int threadStatus = 0;
   ...   
   public synchronized void start() {
        //如果线程状态不是0-新建,则抛异常
        if (threadStatus != 0)
            throw new IllegalThreadStateException();

        //将当前线程添加到线程组
        group.add(this);
		
		//线程是否开启,默认false-未开启
        boolean started = false;
        try {
            //调用native本地方法(最终调用run()方法的核心入口)
            start0();
            //执行完start0,说明线程已正常启动
            started = true;
        } finally {
            try {
                if (!started) {
                    //线程启动失败,则从线程组中将该线程删除
                    group.threadStartFailed(this);
                }
            } catch (Throwable ignore) {
                ...
            }
        }
    }

难点和重点是调用的start0()方法,这是一个native(本地方法/底层方法),源码:

//native本地方法,底层开启异步线程,由JVM创建并启动线程,并最终调用run()方法
private native void start0();

由于Oracle JDK对于native本地方法的源码隐藏了具体实现,可以去Open JDK官方或Github下载源码

以下载open jdk8最新的源码版本jdk8u60为例,需要下载jdkhotspot两种源码来研究


不过现在OpenJDK的源码已经放到GitHub,可以直接去GitHub下载,而且jdk源码和hotspot源码直接放一起了,省事,这里以下载jdk8-b60示例,下载地址:

https://github.com/openjdk/jdk/releases/tag/jdk8-b60

下载完解压,主要关注jdk和hotspot这两个源码目录:
在这里插入图片描述
使用相关工具,比如Scource Insight查看底层方法native stat0具体源码实现
(教程)安装Scource Insight
(教程)使用Scource Insight打开OpenJDK源码
在这里插入图片描述

接下来通过Scource Insight查看底层方法start0是如何一步步,最终由主线程调用Thread#run()方法的源码分析过程

首先查看
源码文件:\jdk-jdk8-b60\jdk\src\share\native\java\lang\ Thread.c
关键源码:JVM_StartThread

static JNINativeMethod methods[] = {
    {"start0",           "()V",        (void \*)&JVM_StartThread},//JVM开启线程的主入口
    {"stop0",            "(" OBJ ")V", (void \*)&JVM_StopThread},
    {"isAlive",          "()Z",        (void \*)&JVM_IsThreadAlive},
    {"suspend0",         "()V",        (void \*)&JVM_SuspendThread},
    {"resume0",          "()V",        (void \*)&JVM_ResumeThread},
    {"setPriority0",     "(I)V",       (void \*)&JVM_SetThreadPriority},
    {"yield",            "()V",        (void \*)&JVM_Yield},
    {"sleep",            "(J)V",       (void \*)&JVM_Sleep},
    {"currentThread",    "()" THD,     (void \*)&JVM_CurrentThread},
    {"countStackFrames", "()I",        (void \*)&JVM_CountStackFrames},
    {"interrupt0",       "()V",        (void \*)&JVM_Interrupt},
    {"isInterrupted",    "(Z)Z",       (void \*)&JVM_IsInterrupted},
    {"holdsLock",        "(" OBJ ")Z", (void \*)&JVM_HoldsLock},
    {"getThreads",        "()[" THD,   (void \*)&JVM_GetAllThreads},
    {"dumpThreads",      "([" THD ")[[" STE, (void \*)&JVM_DumpThreads},
    {"setNativeName",    "(" STR ")V", (void \*)&JVM_SetNativeThreadName},
};

一、网安学习成长路线图

网安所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

二、网安视频合集

观看零基础学习视频,看视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述

三、精品网安学习书籍

当我学到一定基础,有自己的理解能力的时候,会去阅读一些前辈整理的书籍或者手写的笔记资料,这些笔记详细记载了他们对一些技术点的理解,这些理解是比较独到,可以学到不一样的思路。
在这里插入图片描述

四、网络安全源码合集+工具包

光学理论是没用的,要学会跟着一起敲,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

五、网络安全面试题

最后就是大家最关心的网络安全面试题板块
在这里插入图片描述在这里插入图片描述

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

b1fd4edc800d7db3eabb956e.png)

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化资料的朋友,可以点击这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值