别想当然

问题

Java 线程调用start()后会立即执行run()方法吗?

我们在开发中,经常和线程打交道,有些东西总是司空见惯,想当然地认为某些事情理所当然...

但是今天偶然发现一个有趣的现象:

class Test {

public static void main(String[] args) {

System.out.println("hello https://tool.lu/");

Runnable runnable = new Runnable(){

@Override

public void run() {

System.out.println("--run()--");

}

};

Thread thread = new Thread(runnable);

thread.start();

System.out.println("--after start()--");

}

}

运行结果如下:

运行结果

看到运行结果之后,我愣了一下,WTF?

跟我想的有点不一样啊,

理论上来讲,线程调用start()之后,将会调用该线程的run();

我又赶紧去查看了Java的官方文档:JavaAPI

Thread的start()

Cause this thread to begin execution ; the Java Virtual Machine calls the run method of this thread.

通过上面我们可以发现start()就是使该线程开始运行,JVM会调用线程的run()方法。

那我们只能从源码中找答案啦。

/**

* Causes this thread to begin execution; the Java Virtual Machine

* calls the run method of this thread.

*

* The result is that two threads are running concurrently: the

* current thread (which returns from the call to the

* start method) and the other thread (which executes its

* run method).

*

* It is never legal to start a thread more than once.

* In particular, a thread may not be restarted once it has completed

* execution.

*

* @exception IllegalThreadStateException if the thread was already

* started.

* @see #run()

* @see #stop()

*/

public synchronized void start() {

/**

* This method is not invoked for the main method thread or "system"

* group threads created/set up by the VM. Any new functionality added

* to this method in the future may have to also be added to the VM.

*

* A zero status value corresponds to state "NEW".

*/

// Android-changed: throw if 'started' is true

if (threadStatus != 0 || started)

throw new IllegalThreadStateException();

/* Notify the group that this thread is about to be started

* so that it can be added to the group's list of threads

* and the group's unstarted count can be decremented. */

group.add(this);

started = false;

try {

nativeCreate(this, stackSize, daemon);

started = true;

} finally {

try {

if (!started) {

group.threadStartFailed(this);

}

} catch (Throwable ignore) {

/* do nothing. If start0 threw a Throwable then

it will be passed up the call stack */

}

}

}

private native static void nativeCreate(Thread t, long stackSize, boolean daemon);

关键代码已经贴出,但是似乎关键在于nativeCreate()方法。该方法属于c方法,有时间再追踪一下。

思考

通过代码测试我们发现线程调用start()方法,并不会立刻执行run()方法。但是两者之间的时间差是多少呢?

测试用例,有兴趣的朋友can have a try.

把运行结果给出来:

运行结果

通过我的多次测试,run()和start()的时间差一般都在[0,8]之内,当然运行足够多次会发现时间差会更大。

总结

虽然该用例看似没什么卵用,但不亲自上手尝试,还真会回答错...有趣有趣...

需要注意的是如果我们在线程中创建对象,而在start()方法后直接使用该对象,就会出现该问题测试用例。

夫小惑易方,大惑易性...

java线程立刻执行_Java 线程调用start()后会立即执行run()方法吗?相关推荐

  1. java线程池概念_Java 线程池概念、原理、简单实现

    线程池的思想概述 我们使用线程的时候就去创建一个线程,这样实现起来非常简便,但是就会有一个问题: 如果并发的线程数量很多,并且每个线程都是执行一个时间很短的任务就结東了,这样频繁创建线程就会大大降低系 ...

  2. java线程不执行_java线程池,阿里为什么不允许使用Executors?

    带着问题 阿里Java代码规范为什么不允许使用Executors快速创建线程池? 下面的代码输出是什么? ThreadPoolExecutor executor = new ThreadPoolExe ...

  3. java 线程的函数_Java线程总结

    三.    线程间的通信 1.    线程的几种状态 线程有四种状态,任何一个线程肯定处于这四种状态中的一种: 1)    产生(New):线程对象已经产生,但尚未被启动,所以无法执行.如通过new产 ...

  4. java 同步转并行_Java线程与并行编程(二)

    你好,我是goldsunC 让我们一起进步吧! 线程的控制与同步 线程的状态与生命周期 '每个Java程序都有一个默认的主线程,想要实现多线程,必须在主线程中创建新的线程对象.新建的线程在它的一个完整 ...

  5. java 线程 状态 图_Java线程中的生命周期和状态控制图文详解

    这篇文章主要介绍了Java线程的生命周期和状态控制,需要的朋友可以参考下 一.线程的生命周期 线程状态转换图: 1.新建状态 用new关键字和Thread类或其子类建立一个线程对象后,该线程对象就处于 ...

  6. 分析java 线程占用内存_Java线程:保留的内存分析

    分析java 线程占用内存 本文将为您提供一个教程,使您可以确定活动应用程序Java线程中保留了多少Java堆空间 . 将提供来自Oracle Weblogic 10.0生产环境的真实案例研究,以使您 ...

  7. java中一个线程最小优先数_Java线程的优先级

    Java线程可以有优先级的设定,高优先级的线程比低优先级的线程有更高的几率得到执行(不完全正确,请参考下面的"线程优先级的问题"). 记住当线程的优先级没有指定时,所有线程都携带普 ...

  8. java线程详解_Java线程详解

    程序.进程.线程的概念程序(program):是为完成特定任务.用某种语言编写的一组指令的集合.即指一段静态的代码,静态对象. 进程(process):是程序的一次执行过程,或是正在运行的一个程序.动 ...

  9. java线程池示例_Java线程连接示例

    java线程池示例 Java Thread join method can be used to pause the current thread execution until unless the ...

最新文章

  1. python的爬虫库_python做爬虫常用库
  2. iOS原生WebView中JavaScript和OC交互
  3. python3 selenium_Python3+Selenium3自动化测试-(准备)
  4. matlab频谱分析_罗德与施瓦茨两款新的信号和频谱分析仪 具有多种频率型号
  5. 阿里云POLARDB如何帮助百胜软件应对数据库的“巅峰时刻”
  6. Smarty 2、3版本的一些差别
  7. kali linux wps 2019 删除_良心推荐!Linux系统下常用办公软件大盘点
  8. oracle数据库十六进制转字符串,Oracle中各种进制相互转换
  9. 【常用传感器】DS18B20温度传感器原理详解及例程代码
  10. 应用程序无法正常启动0xc0150002 解决方案
  11. raft算法 java实现_Raft 算法在分布式存储系统 Curve 中的实践
  12. npm install 设置缓存
  13. 步进电机的计算机控制系统设计,步进电机控制系统的设计与实现
  14. Java游戏聊斋聂小倩_【聊斋故事汇】之聂小倩(篇一)
  15. 隐藏和isa :进化返祖以及白马非马(c++)
  16. OpenStack高级控制服务之使用编配服务(Heat)实现自动化部署云主机
  17. 错误信息 Error executing DDL via JDBC Statement 解决办法
  18. 奋斗吧,程序员——第五十四章 坐拥美人君莫笑,古来征战几人回
  19. laravel图形验证码(借用了TP的图形验证码类)非常好用简单,非常适合前后端分离的项目
  20. token 微信access 过期_.Net微信开发之如何解决access_token过期问题

热门文章

  1. SEO人生衔接后用户可随时随地同他的合作伙伴协同工作
  2. 【原创】FlashFXP_4.0.0.1510 值得研究
  3. 英国电信前掌门韦华恩出任阿尔卡特朗讯CEO
  4. IBM推新编码系统 实现高清视频技术大突破
  5. 7年专科生程序员同时去腾讯和微软面试,问HR结果以为听错了,结局反转!!
  6. 编程大白给编程小白的四点建议
  7. css和css的圣杯布局,CSS布局--圣杯布局和双飞翼布局以及使用Flex实现圣杯布局
  8. sql去重复查询distinct_SQL的简单查询
  9. Blizzard Transitions for Mac - 动态风雪过渡效果FCPX转场
  10. 这是一款深受学生党喜爱的PDF阅读器