其实,剖析Java线程的内部实现,可以看到Java内部的很多方法都是native修饰的,如
public static native Thread currentThread();
public static native void yield();
public static native void sleep(long millis) throws InterruptedException;
这也就是说,Java线程的实现应该说是基于所处的操作系统的,Java线程的实现并非是“平台无关”。这种实现,很可能是出于高效性的考虑,毕竟,平台相关与高效性是相关的。这也是JDK提供不同平台版本的原因吧。
线程实现的方式是很多的,如内核线程的实现方式、使用用户线程实现、使用用户线程加轻量级进程混合实现。而,Java线程在Windows及Linux平台上的实现方式,现在看来,是内核线程的实现方式。这种方式实现的线程,是直接由操作系统内核支持的——由内核完成线程切换,内核通过操纵调度器(Thread Scheduler)实现线程调度,并将线程任务反映到各个处理器上。内核线程是内核的一个分身。程序一般不直接使用该内核线程,而是使用其高级接口,即轻量级进程(LWP),也即线程。这看起来可能很拗口。看图:
(说明:KLT即内核线程Kernel Thread,是“内核分身”。每一个KLT对应到进程P中的某一个轻量级进程LWP(也即线程),期间要经过用户态、内核态的切换,并在Thread Scheduler 下反应到处理器CPU上。)
这种线程实现的方式也有它的缺陷:在程序面上使用内核线程,必然在操作系统上多次来回切换用户态及内核态;另外,因为是一对一的线程模型,LWP的支持数是有限的。
后记:
关于这篇blog的观点,应该说,大部分都来自《深入理解Java虚拟机》这本书。
参考《深入理解Java虚拟机:JVM高级特性与最佳实践 —— 第五部分 高效并发 》