线程的实现有以下三种方式
- 内核线程实现
- 用户线程实现
- 用户线程加轻量级进程混合实现
1.使用内核线程实现
内核线程
(Knernel-Level Thread,KLT)是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操纵调度器(Scheduler)对线程进行调度,并负责将线程的任务映射到各个处理器上。
程序一般不会直接去使用内核线程,而是去使用内核线程的一种高级接口-轻量级进程(Light Weight Proess,LWP),每个轻量级进程都由一个内核线程支持,因此只有先支持内核线程,才能有轻量级进程。这种轻量级进程与内核线程之间1:1的关系称为一对一的线程模型
关系图如下
局限性:
-
由于是基于内核线程实现的,所以各种线程操作(如创建,析构,同步)都需要进行系统调用,而系统调用代价相对较高,需要在用户态,和内核态中来回切换
-
每个轻量级进程都需要有一个内核线程的支持,因此轻量级进程要消耗一定的内核资源(如内核的栈空间),因此一个系统的轻量级进程是有限的。
2.使用用户线程
从狭义上讲,用户(User Thread)线程指的是完全建立在用空间的线程库上,系统内核不能感知线程存在的实现。 用户线程的建立,同步,和调度完全在用户态中完成。不需要内核的帮助。因此这种操作是非常快速而且低消耗的,也可以支持更大规模的线程数量
劣势:
使用用户线程,所有的线程都需要用户程序自己处理,线程的创建,切换和调度,都是由用户程序自己处理,而操作系统只把处理器资源分配到进程。诸如“阻塞如何处理,多处理器系统如何将线程映射到其他处理器上”这类问题都将异常困难甚至不可能完成。Java曾经使用郭用户线程,最终又放弃了。
3、使用用户线程加轻量级进程混合实现
在这种模式下,既存在用户线程,也存在轻量级进程。
在这种模式下,用户线程完全建立在用户空间,因此,线程的创建,切换,析构等操作依然廉价,并且可以支持大规模并发。而操作系统提供支持轻量级进程则作为用户线程和内核线程之间的桥梁,这样可以使用内核提供的线程调度
功能及处理器映射
参考文献
《深入理解Java虚拟机 JVM高级特性与最佳实践》 周志明