Java协程编程之Loom项目尝鲜

《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
前提

之前很长一段时间关注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项目简单介绍


Loom - Fibers, Continuations and Tail-Calls for the JVM

Loom 项目的标题已经凸显了引入的三大新特性:

  • Fibers :几年前看过当时的 Loom项目的测试代码就是使用Fiber 这个API (现在这个 API 已经被移除),意为轻量级线程,即协程,又称为轻量级用户线程,很神奇的是在目前的 JDK 中实际上称为 Virtual Thread ( 虚拟线程 )

  • Continuations :直译为"连续",实现上有点像闭包,参考不少资料,尚未准确理解其具体含义,感觉可以"粗暴"解读为"程序接下来要执行什么"或者"下一个要执行的代码块"

  • Tail-Calls :尾调用VM 级别支持

三个新特性不详细展开,目前只是 EA 版本,还存在修改的可能性,所以也没必要详细展开。

Virtual Thread使用


当前版本 Loom 项目中协程使用并没有引入一个新的公开的虚拟线程VirtualThread 类,虽然真的存在 VirtualThread ,但这个类使用 default 修饰符,隐藏在java.lang 包中,并且 VirtualThreadThread 的子类。协程的创建 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

最后

由于篇幅原因,就不多做展示了
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!
mg-ZYWhrqWs-1714443315067)]

[外链图片转存中…(img-4SxnxbFN-1714443315067)]

[外链图片转存中…(img-NkaYVt9f-1714443315067)]

由于篇幅原因,就不多做展示了
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》点击传送门,即可获取!

  • 9
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值