转载

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

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

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

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

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

Runtime.getRuntime().availableProcessors();

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

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

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

参考地址

  • http://www.hongyanliren.com/2015m07/35068.html

如果大家喜欢我的文章,可以关注个人订阅号。欢迎随时留言、交流。如果想加入微信群的话一起讨论的话,请加管理员简栈文化-小助手(lastpass4u),他会拉你们进群。

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

原文  http://www.cyblogs.com/javaxian-cheng-yu-linuxnei-he-xian-cheng-de-ying-she-guan-xi/
正文到此结束
Loading...