thread的start()

100 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情

image.png 源码标记解读:

①当多次调用start(),会抛出throw new IllegalThreadStateException()异常。也就是每一个线程类的对象只允许启动一次,如果重复启动则就抛出此异常。

为什么线程的启动不直接使用run()而必须使用start()呢?

1、如果直接调用run()方法,相当于就是简单的调用一个普通方法。

那么为什么必须要用start0方法启动多线程呢 ?在Java程序执行的过程之中考虑到对于不同层次开发者的需求,所以其支持有本地的操作系统函数调用,而这项技术就被称为JNI(Java Native lnteface) 技术,但是Java开发过程之中并不推荐这样使用,利用这项技术可以使用一些操作系统提供底层函数进行一些特殊处理,而在Thread类里面提供的start00就表示需要将此方法依赖于不同的操作系统实现。

如下图:

image.png

任何情况下,启动都必是thread的start方法启动线程。

线程生命周期

Java 线程在运行的生命周期中的指定时刻只可能处于下面 6 种不同状态的其中一个状态,这几个状态在Java源码中用枚举来表示。

  1. NEW:实例化一个Thread类对象出来(未执行start()方法前),Thread的状态为NEW。
  2. RUNNABLE:调用线程的start()方法,此时线程进入RUNNABLE状态,该状态的线程位于可运行线程池中,等待被操作系统调度,获取CPU的使用权。

当获得CPU的时间片时,线程进入运行状态,执行程序代码。

  1. BLOCKED:当线程等待获取monitor锁(synchronized)时,线程就会进入BLOCKED状态。

注意:

  • 等待获取monitor锁,线程的状态是BLOCKED。
  • 等待获取Lock锁(LockSupport.park()),线程的状态是WAITING。
  1. WAITING:等待
  2. TIMED_WAITING:等待一定时间
  3. TERMINATED:死亡

image.png

图中 wait到 runnable状态的转换中,join实际上是Thread类的方法,但这里写成了Object

1、由上图可以看出:线程创建之后它将处于 NEW(新建)  状态,调用 start() 方法后开始运行,线程这时候处于 READY(可运行)  状态。可运行状态的线程获得了 CPU 时间片(timeslice)后就处于 RUNNING(运行)  状态。

2、操作系统隐藏 Java 虚拟机(JVM)中的 READY 和 RUNNING 状态,它只能看到 RUNNABLE 状态,所以 Java 系统一般将这两个状态统称为 RUNNABLE(运行中)  状态 。

3、调用sleep()方法,会进入Blocked状态。sleep()结束之后,Blocked状态首先回到的是Runnable状态中的Ready(也就是可运行状态,但并未运行)。只有拿到了cpu的时间片才会进入Runnable中的Running状态。