Java中多线程启动,为什么调用的是start方法,而不是run方法?

举报
经典鸡翅 发表于 2022/02/17 22:36:41 2022/02/17
【摘要】 前言 大年初二,大家新年快乐,我又开始码字了。写这篇文章,源于在家和基友交流的时候,基友问到了,我猛然发现还真是这么回事,多线程启动调用的都是start,那么为什么没人掉用run呢?于是打开我的idea,翻一波代码,带大家一探究竟。 继承thread类实现多线程 我们知道java有三种方式实现多线程,这里直接用继承的方...

前言

大年初二,大家新年快乐,我又开始码字了。写这篇文章,源于在家和基友交流的时候,基友问到了,我猛然发现还真是这么回事,多线程启动调用的都是start,那么为什么没人掉用run呢?于是打开我的idea,翻一波代码,带大家一探究竟。

继承thread类实现多线程

我们知道java有三种方式实现多线程,这里直接用继承的方式进行试验,其他方式同理。我们要做的是首先声明一个线程。然后去调用,最终根据结果归纳run和start的区别。
定义一个线程类。


   
  1. class MyThread extends Thread {
  2. private String title;
  3. public MyThread(String title) {
  4. this.title = title;
  5. }
  6. @Override
  7. public void run() {
  8. for(int x = 0; x < 5 ; x++) {
  9. System.out.println(this.title + "运行,x = " + x);
  10. }
  11. }
  12. }

在我们的主类中,起三个线程,看看调用的结果。代码如下:


   
  1. public class ExtendsThread {
  2. public static void main(String[] args) {
  3. new MyThread("线程A").start();
  4. new MyThread("线程B").start();
  5. new MyThread("线程C").start();
  6. }
  7. }

直接运行main方法。
观察结果我们发现,三个线程随机交替执行,取决于cpu的调度。


我们再使用run方法来进行调用,查看结果

   
  1. public class ExtendsThread {
  2. public static void main(String[] args) {
  3. new MyThread("线程A").run();
  4. new MyThread("线程B").run();
  5. new MyThread("线程C").run();
  6. }
  7. }

结果如下:


看到这里细心的小伙伴发现了,这个run方法好像是顺序执行的啊!
的确是的,run方法并不会实现多线程。而是顺序执行。那么为什么会产生这样的结果呢?

根本原因

查看run方法的源代码


我们发现run方法只是简单的调用了实现类的run。没有进行任何的多线程处理。

查看start方法的源码


start方法就不一样了。我们可以看到关键的代码就是start0方法。var1理解为线程为启动,调用start0后,线程启动。继续追踪start0.

这个是一个使用jni的java本地方法,jvm根据不同的平台,调度的线程方法不同。
借用一张网上图,一目了然。

start() 方法调用 start0() 方法后,该线程并不一定会立马执行,只是将线程变成了可运行状态。具体什么时候执行,取决于 CPU ,由 CPU 统一调度。

总结

Java 中实现真正的多线程是 start 中的 start0() 方法,run() 方法只是一个普通的方法。

文章来源: blog.csdn.net,作者:经典鸡翅,版权归原作者所有,如需转载,请联系作者。

原文链接:blog.csdn.net/hanqing456/article/details/113801097

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。