
篇首说明: 本文十分冗长, 语言组织混乱, 如果觉得 TLDR, 就直接跳到 关于虚拟线程的总结 部分看要点, 若对总结上中的某些要素点仍有兴趣的话请倒查本文中其他部分的内容. 个人对 Java 虚拟线程的主动研究是为了在项目中更有效的使用它.
关于线程的概要
Java 21 于两年前 2023 年 9 月份放出,它是一个 LTS(long term support) 版本,个人基本就是把 LTS 当作能在正式项目中使用的版本。 Java 21 有几个增进编程体验的特性,像 Sequenced Collections, Record Patterns, 和 Pattern Matching for switch, 而对于性能改进的, 也是 Java 21 最具代表的特性无疑就是 Virtual Threads -- 虚拟线程。本文单列出它来,着重感受一下虚拟线程是什么,以及我们应该如何使用它。
其实在之前的 Java 19, 20 新特性学习 就有一定的笔墨介绍了于 Java 19 引入, Java 20 中尚处于第二次预览的虚拟线程。于其中大致体验了在一台 36 G 物理内存,默认堆内存为 9 G 的情况下, 创建 9000 个线程没问题,但要创建 10000 个线程就 OutOfMemoryError 了。而相同的环境下创建一百万个虚拟线程都没问题,没在继续往下试探了。
其实这种比较是没有意义的, Java 线程对应到平台线程的, 每个线程要至少实实在在的 2M 栈空间, 而一百万个虚拟线程相当于是创建了一百万个 Java 对象而已, 更像是相应数量的 Task, 实际运行时才由载体线程去调度执行 - (注: 后面所提到的载体线程和平台线程是同一个概念).
重新回顾一下何谓虚拟线程,Java 的虚拟线程实现是来自于 Project Loom 项目。与此相关的概念有线程,协程,以及纤程(Fiber),而虚拟线程对应的应该是纤程。
- 线程是操作系统最小的调度单位,每个线程有独立较大的栈空间(比如 2M),内核调度,切换开销大,可有效使用 CPU 多核
- 协程在单个线程内执行,共享线程栈空间或独立小空间,用户态调度,切换开销极小,但无法使用多核
- 纤程,介于线程与协程之间,很小的独立栈,用户态调度,切换开销较小。结合线程池,纤程可在线程间转移,这时岂不是要经内核态调度吗?
经过足足 3 周的时间终于把博客 https://yanbin.blog 从 AWS Lightsail 主机的 WordPress 迁移到了 Hugo 搭建的 GitHub Pages 上。 从动态页面转换成纯静态页,访问时确实是飞快,至少是从北美访问每个半秒以下开。
本来一个博客网站就没有必要搞成动态的,之前网站由于操作系统,WordPress, 和数据库的升级,一段时间以来常出现网站无法访问,1G 内存都顶不住, 后经 一番 Apache, MySQL, 系统调优才得以解决,不过 WordPress 再如何使用文件缓存性能都比静态页面差许多。
快速回顾一下本博客的历史,2006 年前 QQ 空间,后来 blogcn.com, 再到 blogjava.net,2010 年始声请了 unmi.cc 域名, 租 VPS 自搭 WordPress 服务,后面就不断的换 VPS 提供商,也出现过数据少量丢失的现象,所以有些图片或附件不可考。由于 unmi.cc 无法顺利迁出才有了新的 yanbin.blog 域名, 所以博文中还有不少 unmi.cc 的影子,以至于 unmi.cc 被人注册了,并且还堂而皇之的建立了一个李鬼网站,其中很多标题是盗用我的,内容全是 AI 生成。
Read More