user-level thread,kernel-level thread and hybrid threads
问题起始
早上看一篇"某书"上的一篇博客:说到一应用程序(单个进程)中的线程是无法并行执行的,然后我想到了JVM,难道之前学的多线程并行,并不适用与JVM。艾玛,瞬间内心就开始恐慌了,之前学习GC时的并行收集器咋回事哩,Netty的线程池数最佳设置为服务器内核个数时咋回事哩,于是开始怀疑那篇博客的正确性。
上班的路上开始在一个大神云集的微信群里开始讨论起来,有人不清楚,有人不甚了解,有的大神了解的很透彻,各自都发表着自己的看法,最终定位到了解决这个问题的根源。拨开云雾见月明
如下是群里比较有价值的聊天记录:
最早 UNIX 的调度是以 “进程” 为最小调度单位,那个时候还没有线程的概念。线程有两种,一种是 “用户态线程” ,对内核不可见,内核不可以调度,现在一般叫做纤程或协程。另一种是 “内核态线程”,由内核调度,也称作轻量进程 LWP 。现在说的线程,一般不特殊指定,都是内核线程。
内核线程可以调度,用户线程不可以,有点懵
kernel thread 可以利用多 CPU , user thread 不能利用多 CPU
JVM是kernel thread
一个操作系统线程对于一个lwp klt
Linux 2.6上的HotSpot使用了NPTL机制,JVM线程跟内核轻量级进程有一一对应的关系。线程的调度完全交给了操作系统内核,当然jvm还保留一些策略足以影响到其内部的线程调度,举个例子,在linux下,只要一个Thread.run就会调用一个fork产生一个线程。
KLT即内核线程Kernel Thread,是“内核分身”
每一个KLT对应到进程P中的某一个轻量级进程LWP(也即线程)
下面是到公司后网上查的资料,解决了JVM并行的疑惑
线程有三种实现模型:
- 用户级或应用程序级线程
- 内核级线程
- 用户级和内核级混合线程
图6-1显示了3种线程实现模型。图6-1(a)显示了用户级线程,图6-1(b)显示了内核级线程,图6-1(c)则显示了用户线程和内核线程的混合。
用户级线程
内核级线程:
(c) 混合线程:多对多的关系 图6-1(续)
这些实现之间的较大的区别之一就是它们的模式以及要指派给处理器的线程的能力。这些线程运行在用户模式下或内核模式下。
在用户模式下,进程或线程是执行程序或链接库中的指令,它们不对操作系统内核进行任何调用。 在内核模式下,进程或线程是在进行系统调用,例如访问资源或抛出异常。同时,在内核模式下,进程或线程可以访问在内核空间中定义的对象总结:
单进程多用户线程可并发不可并行
单进程内核线程可并发可并行