使用内核线程实现
内核线程(Kernel-Level Thread, KLT)就是直接由操作系统内核支持的线程,这种线程由内核来完成线程切换,内核通过操作调度器(Sheduler)对线程进行调度,并负责将线程的任务映射到各个处理器上。程序一般不会直接使用内核线程,而是去使用内核线程的高级接口——轻量级进程(Light Weight Process)LWP,每个轻量级进程都是由一个内核线程支持,这种1:1的关系称为一对一的线程模型。
由于是基于内核线程实现,所以各种线程操作,如创建、析构、同步都需要进行系统调用, 而系统调用代价比较大,都需要用户态和内核态之间切换,其次,轻量级进程消耗一定的内核资源,因此一个系统支持的轻量级进程的数量是有限的。
使用用户线程实现
用户线程指的是完全建立在用户空间的线程库上,系统内核不能感知线程存在的实现,用户线程的建立、同步、销毁和调度完全在用户态中完成,不需要内核的帮助,如果程序实现得当,这种线程不用切换到内核态,因此操作是非常快速而且低消耗的,也可以支持规模更大的线程数。这种进程和用户线程之间1:N的关系称为一对多的线程模型。
使用用户线程的优势在于不需要系统内核支援,劣势也在于没有系统内核支持,那么所有的线程操作都需要用户程序自己处理,线程的创建、切换、调度、如何映射到处理器,这些问题都将是非常复杂难以实现。
使用用户线程加轻量级进程混合实现
这种混合实现下,既有用户线程也存在轻量级进程。用户线程还是完全建立在用户态上,因此用户线程的创建、切换、析构依然廉价,并且可以支持大规模的线程数量。而操作系统提供支持的轻量级进程作为用户线程和内核线程之间的桥梁,这样就可以使用内核提供的线程调度能力及处理器映射。这中N:M的关系就是多对多的线程模型。
Java线程调度
线程调度是指系统为线程分配处理器使用权的过程。
协同式线程调度
使用协同式协程调度系统,线程的执行时间是由线程本身控制,线程把自己执行完后,主动通知系统切换到另一个线程。
优点:实现简单、没有线程同步问题
缺点:线程执行时间不可控
抢占式线程调度
使用抢占式线程调度系统,线程执行时间将由系统分配。
优点:线程执行时间可控
缺点:需要解决线程同步问题