面试题答案
一键面试线程创建过程
start
方法调用:当在Java代码中调用线程实例的start
方法时,首先会触发一系列的Java层检查,例如确保线程尚未启动等。- 本地方法调用:
start
方法内部调用了本地方法start0
,这是一个JNI(Java Native Interface)方法。这个本地方法由JVM的C/C++ 代码实现。 - 操作系统线程创建:在JVM的C/C++ 实现中,会通过操作系统提供的线程创建函数(如在Linux上可能是
pthread_create
,在Windows上可能是CreateThread
)来创建一个真正的操作系统线程。这一步涉及到操作系统内核资源的分配,例如为线程分配栈空间等。
线程调度
- 线程状态转换:线程创建后,进入
NEW
状态,调用start
方法后,线程进入RUNNABLE
状态。RUNNABLE
状态意味着线程具备了运行的条件,但并不一定正在运行,它需要等待JVM的线程调度器分配CPU时间片。 - 线程调度器:JVM拥有自己的线程调度器,它负责管理和调度处于
RUNNABLE
状态的线程。调度器基于一定的调度算法(如抢占式调度)来决定哪个线程可以获得CPU时间片执行。在抢占式调度中,具有较高优先级的线程可以抢占正在运行的低优先级线程的CPU时间片。 - 操作系统协作:JVM的线程调度器与操作系统的线程调度机制相互协作。操作系统提供了基本的线程调度功能,JVM在其基础上进行更细粒度的Java线程管理。例如,当一个Java线程因为I/O操作等原因进入
BLOCKED
或WAITING
状态时,JVM会通知操作系统释放相应的CPU资源,当线程重新进入RUNNABLE
状态时,等待JVM调度器再次分配CPU时间片。
关键系统资源和JVM组件
- 系统资源:
- CPU资源:线程执行需要CPU时间片,操作系统和JVM调度器共同管理CPU资源的分配。
- 内存资源:每个线程都有自己独立的栈空间用于存储局部变量、方法调用等信息,这需要分配内存资源。同时,线程之间共享堆内存等其他内存区域。
- 文件描述符等资源:如果线程涉及I/O操作,会使用到文件描述符等系统资源。
- JVM组件:
- Java线程对象:在Java层面代表线程,包含线程的状态、优先级等信息,以及
start
、run
等方法。 - JNI:作为Java与本地代码的桥梁,负责在Java层调用本地方法来创建和管理操作系统线程。
- JVM线程调度器:负责在Java层面调度处于
RUNNABLE
状态的线程,决定线程何时获得CPU时间片执行。 - 运行时数据区:其中的栈空间为每个线程私有,堆空间为线程共享,这些数据区为线程执行提供了内存环境。
- Java线程对象:在Java层面代表线程,包含线程的状态、优先级等信息,以及