您的位置 首页 java

Java线程与Linux内核线程的映射关系

java 线程与 Linux 内核线程的映射关系 Linux 从内核2.6开始使用 NPTL (Native POSIX Thread Library) 支持,但这时线程本质上还轻量级进程。

Java 里的线程是由 JVM 来管理的,它如何对应到操作系统的线程是由 JVM 的实现来确定的。 Linux 2.6 上的 HotSpot 使用了 NPTL 机制, JVM线程跟内核轻量级进程有一一对应的关系 。线程的调度完全交给了操作系统内核,当然jvm还保留一些策略足以影响到其内部的线程调度,举个例子,在linux下,只要一个 Thread .run 就会调用一个 fork 产生一个线程。

Java 线程在 Windows 及 Linux 平台上的实现方式,现在看来,是内核线程的实现方式。 这种方式实现的线程,是直接由操作系统内核支持的——由内核完成线程切换,内核通过操纵调度器(Thread Scheduler)实现线程调度,并将线程任务反映到各个处理器上。 内核线程是内核的一个分身。程序一般不直接使用该内核线程,而是使用其高级接口,即轻量级进程( LWP ),也即线程。这看起来可能很拗口。看图:

(说明:KLT即内核线程 Kernel Thread ,是“内核分身”。每一个KLT对应到进程P中的某一个轻量级进程 LWP (也即线程),期间要经过用户态、内核态的切换,并在 Thread Scheduler 下反应到处理器 CPU 上。)

​ 这种线程实现的方式也有它的缺陷:在程序面上使用内核线程,必然在操作系统上多次来回切换用户态及内核态;另外,因为是一对一的线程模型, LWP 的支持数是有限的。

对于一个大型程序,我们可以 开辟的线程数量至少等于运行机器的cpu内核数量 。java程序里我们可以通过下面的一行代码得到这个数量:

  Runtime .getRuntime().availableProcessors();  

所以最小 线程数 量即时 cpu 内核数量。如果所有的任务都是计算密集型的,这个最小线程数量就是我们需要的线程数。开辟更多的线程只会影响程序的性能,因为线程之间的切换工作,会消耗额外的资源。如果任务是IO密集型的任务,我们可以开辟更多的线程执行任务。当一个任务执行 IO 操作的时候,线程将会被阻塞,处理器立刻会切换到另外一个合适的线程去执行。如果我们只拥有与内核数量一样多的线程,即使我们有任务要执行,他们也不能执行,因为处理器没有可以用来调度的线程。

​ 如果线程有50%的时间被阻塞,线程的数量就应该是内核数量的2倍。 如果更少的比例被阻塞,那么它们就是计算密集型的,则需要开辟较少的线程。如果有更多的时间被阻塞,那么就是 IO 密集型的程序,则可以开辟更多的线程。于是我们可以得到下面的线程数量计算公式:线程数量=内核数量 / (1 – 阻塞率)

我们可以通过相应的分析工具或者 java 的 management 包来得到阻塞率的数值。

文章来源:智云一二三科技

文章标题:Java线程与Linux内核线程的映射关系

文章地址:https://www.zhihuclub.com/182554.shtml

关于作者: 智云科技

热门文章

网站地图