了解Java21

发布于:2025-07-17 ⋅ 阅读:(18) ⋅ 点赞:(0)

目前还没有实操过从java8/java11直接到java17,java21。

先储备下知识点,写一些简单例子,以便后续的实操。

一些新特性(java8之后的)

var变量

和前端js定义变量一样了,var搞定

 public static void main(String[] args) {
        var str = "xxx";
        var a = new Object();
        var num = 123;
        System.out.println(num);
        System.out.println(str.getClass().getName());
        System.out.println(a.getClass().getName());
    }

当然有限制:局部变量,for循环引用等地方

多行文本字符串

public static void main(String[] args) {
        String s1 = "第一行\n第二行\n第三行";
        System.out.println(s1);
        System.out.println(s1.length());
        System.out.println("------");

        String s2 = """
                第一行
                第二行
                第三行""";
        System.out.println(s2);
        System.out.println(s2.length());
    }

效果一样
在这里插入图片描述

简单好用的switch case

public class MainSwitch {

    public static void main(String[] args) {
        MainSwitch main = new MainSwitch();
        System.out.println(main.switchTest("one"));
        System.out.println(main.switchTest("two"));
    }

    public String switchTest(String str) {
        return switch (str){
            case "one" -> "1";
            case "two" -> "2";
            default -> "0";
        };
    }
}

虚拟线程

测试如下 确实是虚拟线程快一些。(例子场景是密集的IO请求)

想象多线程为什么慢? 内核开辟资源,多线程的切换,上下文的切换,线程阻塞等待IO…


import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class VirtualThread {

    public static void main(String[] args) throws Exception{
        testThread();
        testVirtualThread();
    }

    public static void testVirtualThread() throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor(); // 每个任务使用虚拟线程

        long startTime = System.currentTimeMillis();

        IntStream.range(0, 100).forEach(i -> {
            executor.submit(() -> {
                try {
                    HttpRequest request = HttpRequest.newBuilder()
                            .version(HttpClient.Version.HTTP_2)
                            .uri(URI.create("http://localhost:8080/health"))
                            .build();
                    client.send(request, HttpResponse.BodyHandlers.ofString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        });

        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.MINUTES);

        System.out.println("Java 21 耗时: " + (System.currentTimeMillis() - startTime) + "ms");
    }


    public static void testThread() throws Exception {
        HttpClient client = HttpClient.newHttpClient();
        ExecutorService executor = Executors.newFixedThreadPool(10); // 限制线程池大小

        long startTime = System.currentTimeMillis();

        IntStream.range(0, 100).forEach(i -> {
            executor.submit(() -> {
                try {
                    HttpRequest request = HttpRequest.newBuilder()
                            .version(HttpClient.Version.HTTP_2)
                            .uri(URI.create("http://localhost:8080/health"))
                            .build();
                    client.send(request, HttpResponse.BodyHandlers.ofString());
                } catch (Exception e) {
                    e.printStackTrace();
                }
            });
        });

        executor.shutdown();
        executor.awaitTermination(1, TimeUnit.MINUTES);

        System.out.println("Java 8 耗时: " + (System.currentTimeMillis() - startTime) + "ms");
    }
}
附:虚拟线程

可以复习下虚拟内存。

首先是"虚"的,并不是实际那么多内存,但是给你的感觉就是很多内存。怎么做到的,做一些虚拟的映射,然后调换更新,给你错觉就可以了。

看看虚拟内存的关键问题?

  1. 地址映射问题:在访问主存时把虚地址变为主存物理地址(这一过程称为内地址变换);在访问辅存时把虚地址变成辅存的物理地址(这一过程称为外地址变换),以便换页。此外还要解决主存分配、存储保护与程序再定位等问题
  2. 调度问题:决定哪些程序和数据应被调入主存
  3. 替换问题:决定哪些程序和数据应被调出主存
  4. 更新问题:确保主存与辅存的一致性

回到虚拟线程。

一样的道理,设计一种轻量级的调度资源。让多个去绑定一个线程,营造出很多线程的感觉,但是不是真正的内核级别线程。只是一种用异步执行框架设计出来的执行单元。

来看看虚拟线程的关键特性

  1. 轻量级:虚拟线程的创建和销毁成本非常低,通常只需要几十个字节的内存。
  2. 自动上下文管理:虚拟线程会自动管理其上下文(例如,局部变量、异常处理器等),使得开发者不需要手动管理这些上下文。
  3. 易于使用:通过异步编程模型,虚拟线程使得编写异步和非阻塞代码变得更加简单和直观。

网站公告

今日签到

点亮在社区的每一天
去签到