• Java Thread之start和run方法的区别


    原创转载请注明出处:https://www.cnblogs.com/agilestyle/p/11421515.html

    start

    用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法,这里方法run()称为线程体,它包含了要执行的这个线程的内容,run方法运行结束,此线程随即终止。

    start方法源码示例

    一个 Java 线程的创建本质上就对应了一个本地线程(native thread)的创建,两者是一一对应的。

    关键问题是:本地线程执行的应该是本地代码,而 Java 线程提供的线程函数(run)是 Java 方法,编译出的是 Java 字节码。

    所以, Java 线程其实提供了一个统一的线程函数,该线程函数通过 Java 虚拟机调用 Java 线程方法 , 这是通过 Java 本地方法 start0 调用来实现的。 

    也就是新创建的线程启动调用native start0方法,而这些native方法的注册是在Thread对象初始化的时候完成的

    Thread 类有个 registerNatives 本地方法,该方法主要的作用就是注册一些本地方法供 Thread 类使用,如 start0(),stop0() 等等,可以说,所有操作本地线程的本地方法都是由它注册的。

    这个方法放在一个 static 语句块中,当该类被加载到 JVM 中的时候,它就会被调用,进而注册相应的本地方法。(查看本地方法的源码需要前往 http://jdk.java.net/java-se-ri/8 下载openjdk的源代码)

    而本地方法 registerNatives 是定义在 Thread.c 文件中的。Thread.c 是个很小的文件,它定义了各个操作系统平台都要用到的关于线程的公用数据和操作,如下: 

    可以看出 Java 线程调用 start->start0 的方法,实际上会调用到 JVM_StartThread 方法,而 JVM_StartThread 最终调用的是 Java 线程的 run 方法。

    在 jvm.cpp 中,有如下代码段:

    这里 JVM_ENTRY 是一个宏,用来定义 JVM_StartThread 函数,可以看到函数内创建了真正的平台相关的本地线程,其线程函数是 thread_entry,如下:

    可以看到调用了 vmSymbols::run_method_name 方法,而 run_method_name 是在 vmSymbols.hpp 用宏定义的: 

    run

    run()方法只是类的一个普通方法而已,如果直接调用Run方法,程序中依然只有主线程这一个线程,其程序执行路径还是只有一条,还是要顺序执行,还是要等待run方法体执行完毕后才可继续执行下面的代码,这样就没有达到写线程的目的。

    run方法源码示例

    分别测试start和run

     1 package org.fool.test.thread;  
     2   
     3 public class ThreadTest {  
     4     public static void main(String[] args) {  
     5         Thread thread = new Thread(new Runnable() {  
     6             @Override  
     7             public void run() {  
     8                 System.out.println(Thread.currentThread().getName() + " invoked...");  
     9             }  
    10         });  
    11         thread.start();  
    12         //thread.run();  
    13     }  
    14 }  

    先运行thread.start()

    Thread-0 invoked...  

    注释调thread.start()方法,运行thread.run()

    main invoked... 

    Summary

    start方法可启动多线程

    run方法只是thread的一个普通方法调用,还是在主线程里执行,是不会开启多线程的

  • 相关阅读:
    Path Sum II
    Convert Sorted Array to Binary Search Tree
    Construct Binary Tree from Inorder and Postorder Traversal
    Construct Binary Tree from Preorder and Inorder Traversal
    Maximum Depth of Binary Tree
    Binary Tree Zigzag Level Order Traversal
    Binary Tree Level Order Traversal
    Same Tree
    Validate Binary Search Tree
    Binary Tree Inorder Traversal
  • 原文地址:https://www.cnblogs.com/agilestyle/p/11421515.html
Copyright © 2020-2023  润新知