1

一个线程的启动是需要通过Thread.start()方法来完成的(也只有start才完成一个线程的真正创建,new Thread不算),这个方法会调用本地方法JNI来实现一个真正意义上的线程,或者说只有start成功调用后由OS分配线程资源,才能叫做线程,而在JVM中分配的Thread对象只是与只对应的外壳。

轻量级进程

线程为轻量级进程,多个线程共享一个进程资源,对于OS的许多资源的分配和管理(例如内存)通常都是进程级别的,线程只是OS调度的最小单位,线程相对进程更加轻量一些,它的上下文信息会更少,它的创建与销毁会更加简单,线程因为某种原因挂起后不会导致整个进程被挂起,一个进程中又可以分配许多的线程。但是某个线程占用过多资源会导致整个进程宕机。线程使用的是堆外内存空间。

启动线程

start方法怎么启动线程的:

(1)基于Kernel Thread(KLT)的映射来实现(Java采用此方案)

clipboard.png

KLT是内核线程,内核线程由OS直接完成调度切换,它相对应用程序的线程来讲只是一个接口,外部程序会使用一种轻量级进程(Light Weight Process,LWP)来与KLT进行一对一的接口调用。也就是说,进程内部会尝试利用OS的内核线程去参与实际的调度,而自己使用API调用作为中间桥梁与自己的程序进行交互。

(2)基于用户线程(User Thread,UT)的实现

clipboard.png

是否可以没有中间这一层映射,自己的线程直接由CPU来调度,或许理论上效率更高。不过这样实现时,用户进程需要关注的抽象层次会更低一些,跳过OS更加接近CPU,即自己要去做许多OS要做的事情,自然的OS的调度算法、创建、销毁、上下文切换、挂起等等都要自己要搞定(CPU只做计算),这样做显然很麻烦,有人尝试了,后来放弃了。

(3)混合实现方式

clipboard.png

设计理念是既希望保留Kernel线程原有的架构,又想使用用户线程,轻量级进程依然与Kernel线程一一对应,唯一的变化就是轻量级进程不再与进程直接挂钩,而是与用户线程挂钩,用户线程不一定必须与轻量级进程一一对应,而是多对多,就像在使用一个轻量级进程列表一样,增加了一层来解除轻量级进程与原进程之间的耦合。


codecraft
11.9k 声望2k 粉丝

当一个代码的工匠回首往事时,不因虚度年华而悔恨,也不因碌碌无为而羞愧,这样,当他老的时候,可以很自豪告诉世人,我曾经将代码注入生命去打造互联网的浪潮之巅,那是个很疯狂的时代,我在一波波的浪潮上留下...