@
bmpidev2019 废弃的原因其实是因为 Linux 的线程实现方式的历史原因。
https://web.archive.org/web/20040211225937/http://java.sun.com/developer/technicalArticles/Programming/linux/注意到:
> ... Each Linux thread is created as a process clone operation, which leaves the scheduling of threads to be a task of the process scheduler.
而彼时的 Linux 内核版本离 2003 年真正实现了内核态的抢占调度( 2.6 版本,CFS 算法)还有 3 年,也就是说,这个时候的 Linux 只支持一个时间一个线程在跑,OS 无法主动抢占当前正在执行的线程,必须由用户侧程序来调用 schedule 。换句话说,这个时候创建的线程受到了 Linux Process Scheduler 的制约( Linux Scheduler 调度的最小单元是 Thread ),无法实现真正的并行(操作系统无法调度到其他 CPU 上),同时,这样实现的 Thread 切换跟 OS Thread 切换是一致的,也受到 OS Thread 切换的制约( Context Switch ,内核态-用户态进出)。
> By comparison, on Solaris the Java threads are mapped onto user threads, which in turn are run on Lightweight processes (LWP). On Windows the threads are created inside the process itself. For this reason, creating a large number of Java threads on Solaris and Windows today is faster than on Linux. This means you might need to adjust programs that rely on platform-specific timing to take a little longer on startup when they run on Linux.
正如你文章引用的 Solaris 调度系统图所说,Solaris 的调度存在 LWP 这个中间单元,这个中间单元其实类比于现在并发的 M:N 实现,实际是比较超前的。LWP 能被自由的调度到多个 Kernel Thread 上,多个 Kernel Thread 也可以被自由地调度到每个 CPU Core 上;而 Windows 的调度也是在 Process 的树形结构下调度的。在这两个系统下,由 JVM 实现的调度器能够自由地把 Task 进行低开销地切换(要么发生在 LWP 间,要么发生在 Process 内),系统调度的时候也不仅仅以 Thread 为单位( LWP-Kernel Thread 或者 Process-Thread ),使得在这两个平台上,Green Thread 的调度都是合理的。
当然,随着后面 Linux 的崛起,Java 1.3 虽然放弃了 Green Thread 实现,但是 Project Loom 又把它带回来了,这也是 OpenJDK 认为的,Java 并发调用的未来。