美文网首页
4-1 启动线程的方式

4-1 启动线程的方式

作者: 西西_20f6 | 来源:发表于2020-07-06 13:34 被阅读0次

    启动线程的正确方式:start()
    一、start()有哪些作用?
    1,启动新线程
    线程对象在初始化之后被Main线程调用了start(),于是当前线程(Main)就会告诉JVM来执行一个新的线程。start()做的最重要的一件事情就是通知我们的JVM在有空闲的情况来开启一个新的线程。所以启动一个新线程的本质就是去请求JVM来运行我们这个新的线程,至于这个新线程何时能被执行,并不是由我们能决定的,是由线程调度器决定的,如果它很忙,即使我们已经调用了start(),它也未必能够马上启动,甚至可能要过好久才会执行。我们调用start()的顺序并不能决定线程执行的先后顺序。

    2,start()其实会让两个线程同时运行
    第一个就是我们的父线程,因为我们必须要有一个父线程来执行start(),第二个才是我们刚刚创建的那个子线程,很多i情况下我们会忽略掉为我们创建线程调用start()的父线程,new Thread().start()被我们的父线程执行之后才会去创建子线程,

    3,start()做了哪些准备工作?
    我们的子线程其实是需要做一些准备工作,才能让它正常运行。
    首先,它会让自己处于就绪状态(Runnable),所谓的就绪状态就是指我已经获取导了除了CPU以外的其他资源。比如说我已经设置了上下文,栈,线程状态以及PC(寄存器,指向我们程序运行的位置),做完了以上准备工作,就只欠CPU资源了。在做完准备工作之后我们的线程才可以被我们的JVM或操作系统进一步去调度到执行状态,调度到执行状态,等待获取CPU资源,然后才会真正进入到运行状态,执行我们run()中的逻辑。

    4,不能重复地执行start()
    否则会抛出IllegalThreadStateException
    一旦线程开始执行就从NEW状态变为其他状态,一旦执行完毕就编程TERMINATED状态,而且不会再返回了。

    二、start()源码解析
    1,启动新线程检查线程状态

    2,加入线程组

    3,调用start0()
    是一个native,每个JDK版本,jvm版本对native方法的实现或许是不一样的。

    启动线程的错误方式:run()
    如果直接调用Runnable.run(),会在当前线程执行Runnable任务。如果要启动新线程执行Runnable,还是要通过Thread去调用Runnable的run().

    CAFE BABE

    三、问题
    1,一个线程两次调用start()会出现什么情况?
    第二次会报错,因为调用start()的时候,检查线程状态,如果不是NEW就会抛出IllegalThreadStateException

    2,既然start()会调用run(),为什么我们选择调用start(),而不是直接调用run()呢?
    直接调用run()是默认在当前线程运行run().而不是在新建的线程中执行

    相关文章

      网友评论

          本文标题:4-1 启动线程的方式

          本文链接:https://www.haomeiwen.com/subject/fysbqktx.html