java中的线程与操作系统线程的关系

270 阅读3分钟

在学习操作系统线程相关的知识时,了解到操作系统的相关模型如下:

一、操作系统线程实现方式:

线程的实现方式在不同的操作系统中有不同的方式,可分为三种:用户级空间下的线程,内核级空间下的线程,组合方式(前两种的结合)。

1.用户级空间下的线程

用户线程指的是线程完全建立在用户空间的线程库上,在操作系统的内核不能感知到线程的存在。用户线程的建立,同步,销毁和调度完全在用户态完成,不需要内核的帮助。

优点:线程的调度只是在用户态,减少了操作系统从内核态到用户态的切换开销

缺点:当某一线程阻塞时,操作系统会阻塞整个进程。如果进程中一个线程长时间不释放CPU,因为用户空间并没有时钟中断机制,会导致此进程中的其它线程得不到CPU而持续等待。非真正意义的线程并行(一个进程安排在单个CPU上)。

2.内核级空间下的线程

内核线程(Kernel-Level Thread KLT)就是直接由操作系统内核支持的线程。但是程序一般不会直接使用内核线程。而是去使用内核线程的一种高级接口——轻量级进程(Light Weight Process,LWP) 。由于每个轻量级进程都由一个内核线程支持,因此轻量级进程与内核线程之间的关系为1:1,也叫一对一的线程模型。

优点:实现了真正意义上的线程并行。

缺点:频繁的模式切换(mode switches)导致内核开支(overhead)。

Java在windows和linux上实现线程的方式就是用的内核级线程。

3.用户线程加轻量级进程混合实现

在这种混合实现下,即存在用户线程,也存在轻量级进程。用户线程还是完全建立在用户空间中,因此用户线程的创建、切换、析构等操作依然廉价,并且可以支持大规模的用户线程并发。而操作系统提供支持的轻量级进程则作为用户线程和内核线程之间的桥梁,这样可以使用内核提供的线程调度功能及处理器映射,并且用户线程的系统调用要通过轻量级进程来完成,大大降低了整个进程被完全阻塞的风险。在这种混合模式中,用户线程与轻量级进程的数量比是不定的,即为N:M的关系:

二、java中线程的实现方式

了解了操作系统中的线程的实现方式,那么java中的线程和操作系统中的关系是怎样的呢,带着疑问打开jdk源码查看。

image.png image.png

当Thread调用start方法时底层会调用一个start0()的native方法,这里其实是创建了一个操作系统的线程。 在线程创建时,其实是先创建一个java线程,等到本地存储、程序计数器、缓冲区等都分配好以后,JVM会调用操作系统的方法,创建一个与java线程绑定的原生线程。线程的调度是由操作系统负责的。当操作系统为线程分配好时间片以后,就会调用java线程的run方法执行该线程。当线程结束后,会释放java线程和原生线程所占用的资源

总结:java中的线程和操作系统中的线程分别存在于虚拟机和操作系统中,他们是一一对应,息息相关的。