有各种文档描述了 Solaris/Linux 上的线程,但现在没有描述 Windows 实现。我对此有过浓厚的兴趣,如此重要的事情(似乎)没有记录在案似乎很奇怪。
线程在不同的操作系统上是不一样的——“一次编写,随处运行”对于线程来说是不正确的。
有各种文档描述了 Solaris/Linux 上的线程,但现在没有描述 Windows 实现。我对此有过浓厚的兴趣,如此重要的事情(似乎)没有记录在案似乎很奇怪。
线程在不同的操作系统上是不一样的——“一次编写,随处运行”对于线程来说是不正确的。
为了最直接地回答您的问题,JVM 规范故意未定义有关如何实现线程的精确语义。
FWIW,Sebastion 的声明“Java 的公开线程模型在每个平台上都是相同的,并在 Java 规范中定义。对于 Java 应用程序,即使是线程,底层操作系统也应该是完全透明的”,这是不准确的。
我发现 Windows 和 Linux 下的线程在使用等待/通知的线程饥饿方面存在显着的经验差异。当许多线程争夺一个锁时, Linux更容易出现饥饿 - 以至于我必须在 Windows 中加载比 Linux 多 3个数量级的线程才能导致饥饿。对于竞争激烈的锁,带有 fair 修饰符的 Java 并发锁变得至关重要。
为了说明数字,我在 Linux 下遇到了一个问题,一个锁被 31 个线程严重竞争,而在 Windows 下,相同的代码需要 10,000 个(是的,即 10,000个)线程才能开始演示饥饿问题。
更糟糕的是,Linux 下出现了 3 种不同的线程模型,每一种都有不同的特性。
大多数情况下,线程在我的经验中是透明的,但争用问题值得仔细考虑。
这实际上取决于特定的 JVM 实现。我假设您想知道 Sun 的 Windows JVM,我可以肯定地告诉您,Sun JVM 将 Java 线程映射到 OS 线程。
您可以尝试从 Java 代码中生成几个线程,打开任务管理器并查看发生了什么。
有问题的文档讨论了 Solaris 线程模型以及 VM 如何映射到它。这与Linux无关。此外,该文档仅讨论性能。无论您选择什么,程序的整体行为都不应改变。
Java 公开的线程模型在每个平台上都是相同的,并在 Java 规范中定义。对于 Java 应用程序,即使对于线程,底层操作系统也应该是完全透明的。
但是,如果您必须知道... Sun JVM 将其线程 1:1 映射到 Windows 线程。它不使用多种工艺或纤维。
该文档更多地是关于 Solaris 线程而不是 Java 线程模型。所有 JVM 都会调用它们所针对的操作系统的本机线程 API,因此一个操作系统线程总是有一个 Java 线程。文档中的图表显示,直到线程在操作系统空间中才发生更改。对于 Windows 特定文档,每个操作系统都可以以不同方式处理线程,这是一个很好的起点:MSDN About Processes and Threads。
很长一段时间以来,*nix 的各种风格都使用进程而不是实际线程来实现它们的线程,似乎那些特定的调整参数可以简化向 Solaris 中更新的线程模型的过渡。这使得旧模型和那些 JVM 选项过时了。
有关 HotSpot JVM 的 JVM 选项列表,您可以查看:HotSpot VM Options。其中很多对于调整长时间运行的应用程序很有用,但如果您不了解它们在做什么,您也可能会遇到麻烦。还要记住,JVM 的每个实现都可以有一组不同的选项,您在 IBM 的 VM 或 BEA 上找不到其中一些选项。