主线程和子线程执行顺序问题

Posted Loong.liu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了主线程和子线程执行顺序问题相关的知识,希望对你有一定的参考价值。

public class MyThread implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName());
    }
}

public class Main {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        new Thread(mt,"子线程对象").start();
        mt.run();
    }
}    

如上面代码。

运行的时候输出:

main
子线程对象

上面输出结果中的"main"是执行mt.run();语句输出的,

而"子线程对象"则是执行.start()语句输出的。

也即前者代表着主进程,后者代表着子进程。

 

在HotSpot VM上,其实mt.run()几乎总是会比.start()调用的run()要早执行,因为Thread.start()在调用(caller)线程上创建好线程就返回了,紧接着就可以去调用执行tt.m2();而在被调用(callee)的新线程上还要经过一些JVM内部的初始化动作才能跑到指定的入口方法。这并不是Java语言规范或者JVM规范所要求的行为,只是在HotSpot VM这种特定实现上会有这样的特征,所以既不应该当作标准行为去依赖。

简单点说就是:.start()新起一个线程去运行run方法,但是对main这个线程来说,他会继续往下走 执行mt.run(),一个是新起线程去执行,一个是在本线程(已经在执行的线程)执行。(在程序运行时,主线程已经启动并在运行中,而另外起一个线程start表示线程处于就绪状态,还要等JVM机制调用进入运行状态)

 

当时debug的时候输出的结果却是反过来。可能是:调用start之后,线程只是处于等待调度的“就绪”状态,并没有启动。调试多线程最好用日志,调试器要么只暂停一个线程,要么全部挂起,容易让人困扰的。

 

如果代码中加一行,如下

new Thread(mt,"子线程对象").start();
Thread.yield();
mt.run();

效果就明显了。

 

总结自网上。

  

 



以上是关于主线程和子线程执行顺序问题的主要内容,如果未能解决你的问题,请参考以下文章

Python_线程线程效率测试数据隔离测试主线程和子线程

主线程和子线程的区别

学习java第19天个人总结

线程优先级

Unity主线程和子线程跳转调用(2)

主线程怎么给子线程发送消息