(搬)Java19 改变游戏的版本

45 阅读2分钟

在长期支持版本17之后,这个新的java版本为那些其他语言忽略或难解决的问题,提供了些简洁易用的方案。

并发

结构化任务域(structured task scope),一个全新的代码块形式,专注于处理并发场景。


Response handle() throws ExecutionException, InterruptedException {

    try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {

        Future<String>  user  = scope.fork(() -> findUser());

        Future<Integer> order = scope.fork(() -> fetchOrder());

  


        scope.join();           // Join both forks

        scope.throwIfFailed();  // ... and propagate errors

  


        // Here, both forks have succeeded, so compose their results

        return new Response(user.resultNow(), order.resultNow());

    }

}

对比下以前的写法


Response handle() throws ExecutionException, InterruptedException {

    // esvc 是一个ExecutorService

    Future<String>  user  = esvc.submit(() -> findUser());

    Future<Integer> order = esvc.submit(() -> fetchOrder());

    String theUser  = user.get();   // Join findUser

    int    theOrder = order.get();  // Join fetchOrder

    return new Response(theUser, theOrder);

}

优势在于findUser()fetchOrder()各自出现错误时,可以节约更多的资源,因为它可以立刻终止所有子任务,放以前,fetchOrder()哪怕一开始就有错,也要在user.get()阻塞完后报错。另外这种写法,使得代码块成为一个单元,要么成功,要么失败。

启用

这玩意是在“恒温箱”模块里(incubator module),听这名字就知道属于孵化期的东西,因此它是默认排除的,使用它需要手动设置一些东西,这里以 IDEA 为例。

在这个位置配置javac的特殊参数,由于我不想污染其他项目,就只针对某个模块配置了。

--release 19 --enable-preview --add-modules=jdk.incubator.concurrent

IDEA javac 设置.png

然后是设置运行时的vm参数

--enable-preview --add-modules jdk.incubator.concurrent

不建议直接改idea.exe.vmoptions的设置,你万一用的不是这个版本的jdk就炸了

简化record类型的使用

直接上代码感受下


record Point(int x, int y){}

  


void printSum(Object o){

    if(o instanceof Point(int x, int y)){

        System.out.println(x+y);

    }

}

虚拟线程

提供了一个轻量化的并发方案,这些虚拟线程由JDK管理,可以在同一个线程上管理大量的虚拟线程,这使得你可以大量地使用它来进行并发,而不是像以前一样创建线程。

使用例子:


try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {

    IntStream.range(0, 10_000).forEach(i -> {

        executor.submit(() -> {

            Thread.sleep(Duration.ofSeconds(1));

            return i;

        });

    });

}  // executor.close() is called implicitly, and waits

此处Executors增加了一个获取虚拟线程的静态方法。

原文链接