前提
之前很长一段时间关注JDK
协程库的开发进度,但是前一段时间比较忙很少去查看OpenJDK
官网的内容。 Java 协程项目 Loom
(因为项目还在开发阶段, OpenJDK
给出的官网 https://openjdk.java.net/projects/loom 中只有少量 Loom
项目相关的信息)已经在 2018 年之前立项,目前已经发布过基于 JDK17
编译和JDK18
编译等早期版本,笔者在下载 Loom
早期版本的时候只找到 JDK18
编译的版本:
下载入口在: https://jdk.java.net/loom
由于该 JDK
版本过高,目前可以使用主流 IDE
导入 Loom-JDK-18+9
进行代码高亮和语法提醒,暂时找不到方法进行编译,暂时使用该 JDK
执行目录下的的 javac
命令脚本进行编译,使用 java
命令脚本运行。
Loom - Fibers, Continuations and Tail-Calls for the JVM
Loom 项目的标题已经凸显了引入的三大新特性:
-
Fibers
:几年前看过当时的Loom
项目的测试代码就是使用Fiber
这个API
(现在这个API
已经被移除),意为轻量级线程,即协程,又称为轻量级用户线程,很神奇的是在目前的JDK
中实际上称为Virtual Thread ( 虚拟线程 )
-
Continuations
:直译为"连续",实现上有点像闭包,参考不少资料,尚未准确理解其具体含义,感觉可以"粗暴"解读为"程序接下来要执行什么"或者"下一个要执行的代码块" -
Tail-Calls
:尾调用VM
级别支持
三个新特性不详细展开,目前只是 EA
版本,还存在修改的可能性,所以也没必要详细展开。
当前版本 Loom
项目中协程使用并没有引入一个新的公开的虚拟线程VirtualThread
类,虽然真的存在 VirtualThread
,但这个类使用 default
修饰符,隐藏在java.lang
包中,并且 VirtualThread
是 Thread
的子类。协程的创建 API
位于 Thread
类中:
当前版本 Loom
项目中协程使用并没有引入一个新的公开的虚拟线程 VirtualThread
类,虽然真的存在 VirtualThread
,但这个类使用 default
修饰符,隐藏在 java.lang
包中,并且 VirtualThread
是 Thread
的子类。协程的创建 API
位于 Thread
类中:
使用此 API
创建协程如下:
public static void main(String[] args) {
Thread fiber = Thread.startVirtualThread(() -> System.out.println(“Hello Fiber”));
}
从当前的源码可知:
VirtualThread
会通过 Thread.currentThread()
获取父线程的调度器,如果在 main 方法运行,那么上面代码中的协程实例的父线程就是 main
线程
默认的调度器为系统创建的 ForkJoinPool
实例( VirtualThread.DEFAULT_SCHEDULER )
,输入的 Runnable
实例会被封装为RunContinuation
,最终由调度器执行
对于timed unpark
(正在阻塞,等待唤醒)的协程,使用系统创建的ScheduledExecutorService
实例进行唤醒
这个静态工厂方法创建完协程马上运行,返回的是协程实例
如果按照上面的 Thread.startVirtualThread()
方法去创建协程,显然无法定义协程的名称等属性。Loom
项目为 Thread
类引入了建造者模式,比较合理地解决了这个问题:
// 创建平台线程建造器,对应于Thread实例
public static Builder.OfPlatform ofPlatform() {
return new ThreadBuilders.PlatformThreadBuilder();
}
// 创建虚拟线程建造器,对应于VirtualThread
public static Builder.OfVirtual ofVirtual() {
return new ThreadBuilders.VirtualThreadBuilder();
}
简单说就是:
ofPlatform()
方法用于构建Thread
实例,这里的 Platform Thread (平台线程)
其实就是 JDK1.0
引入的线程实例,普通的用户线程
ofVirtual()
方法用于构建 VirtualThread
实例,也就是构建协程实例
这两个建造器实例的所有 Setter
方法链展开如下:
public static void main(String[] args) {
Thread.Builder.OfPlatform platformThreadBuilder = Thread.ofPlatform()
// 是否守护线程
.daemon(true)
// 线程组
.group(Thread.currentThread().getThreadGroup())
// 线程名称
.name(“thread-1”)
// 线程名称前缀 + 起始自增数字 => prefix + start,下一个创建的线程名称就是prefix + (start + 1)
// start > 0的情况下会覆盖name属性配置
.name(“thread-”, 1L)
// 是否启用ThreadLocal
.allowSetThreadLocals(false)
// 是否启用InheritableThreadLocal
.inheritInheritableThreadLocals(false)
// 设置优先级
.priority(100)
// 设置线程栈深度
.stackSize(10)
// 设置未捕获异常处理器
.uncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
}
});
// thread-1
Thread firstThread = platformThreadBuilder.unstarted(() -> System.out.println(“Hello Platform Thread First”));
// thread-2
Thread secondThread = platformThreadBuilder.unstarted(() -> System.out.println(“Hello Platform Thread Second”));
Thread.Builder.OfVirtual virtualThreadBuilder = Thread.ofVirtual()
// 协程名称
.name(“fiber-1”)
// 协程名称前缀 + 起始自增数字 => prefix + start,下一个创建的协程名称就是prefix + (start + 1)
// start > 0的情况下会覆盖name属性配置
.name(“fiber-”, 1L)
// 是否启用ThreadLocal
.allowSetThreadLocals(false)
// 是否启用InheritableThreadLocal
.inheritInheritableThreadLocals(false)
// 设置调度器,Executor实例,也就是调度器是一个线程池,设置为NULL会使用VirtualThread.DEFAULT_SCHEDULER
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
基本涵盖了95%以上Java开发知识点,不论你是刚入门Android开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!