经典台球
78.8MB · 2026-02-23
JDK 21(2023年9月发布)是Java的长期支持(LTS)版本,引入了多项重要特性和性能改进。作为继JDK 17之后的又一个LTS版本,JDK 21在保持兼容性的同时,提供了更现代、更高效、更简洁的语言特性和API,为Java开发者带来了更好的开发体验和性能表现。
特性说明:
核心概念:
创建方式:
Thread.startVirtualThread():直接启动一个虚拟线程Thread.ofVirtual():创建虚拟线程构建器Executors.newVirtualThreadPerTaskExecutor():创建虚拟线程执行器代码示例:
public static void demonstrateVirtualThreads() throws Exception {
System.out.println("=== 虚拟线程示例 ===");
// 创建虚拟线程的几种方式
System.out.println("1. 使用Thread.startVirtualThread");
Thread virtualThread1 = Thread.startVirtualThread(() -> {
System.out.println("虚拟线程执行: " + Thread.currentThread());
});
virtualThread1.join();
System.out.println("n2. 使用Thread.ofVirtual()");
Thread virtualThread2 = Thread.ofVirtual()
.name("my-virtual-thread-", 0)
.start(() -> {
System.out.println("命名的虚拟线程: " + Thread.currentThread().getName());
});
virtualThread2.join();
System.out.println("n3. 使用Executors.newVirtualThreadPerTaskExecutor");
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
List<Future<String>> futures = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
final int taskId = i;
Future<String> future = executor.submit(() -> {
Thread.sleep(100); // 模拟IO操作
return "任务 " + taskId + " 完成 by " + Thread.currentThread();
});
futures.add(future);
}
// 获取结果
for (Future<String> future : futures) {
System.out.println(future.get());
}
}
// 演示虚拟线程的轻量级特性
System.out.println("n4. 创建大量虚拟线程");
long startTime = System.currentTimeMillis();
int numberOfThreads = 10000;
CountDownLatch latch = new CountDownLatch(numberOfThreads);
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < numberOfThreads; i++) {
final int threadId = i;
executor.submit(() -> {
try {
Thread.sleep(100); // 模拟IO等待
System.out.print(".");
if (threadId % 1000 == 0) {
System.out.println(" [" + threadId + "]");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
latch.countDown();
}
});
}
latch.await(); // 等待所有任务完成
}
long endTime = System.currentTimeMillis();
System.out.println("n创建 " + numberOfThreads + " 个虚拟线程耗时: " +
(endTime - startTime) + "ms");
}
性能优势:
适用场景:
特性说明:
核心概念:
record关键字定义的不可变类代码示例:
// 记录类定义
record Point(int x, int y) {
public double distanceTo(Point other) {
int dx = x - other.x;
int dy = y - other.y;
return Math.sqrt(dx * dx + dy * dy);
}
}
record CircleRecord(Point center, double radius) {
public double area() {
return Math.PI * radius * radius;
}
}
record Position(Point point) {
// 包装类示例
}
record RectangleRecord(Position upperLeft, Position lowerRight) {
public double width() {
return Math.abs(lowerRight.point().x() - upperLeft.point().x());
}
public double height() {
return Math.abs(lowerRight.point().y() - upperLeft.point().y());
}
public double area() {
return width() * height();
}
}
// 使用记录模式
public static void demonstrateRecordPatterns() {
System.out.println("n=== 记录模式示例 ===");
List<Object> objects = Arrays.asList(
new Point(10, 20),
new CircleRecord(new Point(5, 5), 8.0),
"Just a string",
42
);
for (Object obj : objects) {
String description = processObject(obj);
System.out.println(description);
}
// 嵌套记录模式
System.out.println("n--- 嵌套记录模式 ---");
RectangleRecord rect = new RectangleRecord(
new Position(new Point(0, 0)),
new Position(new Point(10, 10))
);
if (rect instanceof RectangleRecord(Position(Point upperLeft), Position(Point lowerRight))) {
System.out.println("矩形: 左上角(" + upperLeft.x() + "," + upperLeft.y() +
"), 右下角(" + lowerRight.x() + "," + lowerRight.y() + ")");
}
}
private static String processObject(Object obj) {
// 记录模式在switch中的使用
return switch (obj) {
case Point(int x, int y) ->
String.format("点坐标: (%d, %d)", x, y);
case CircleRecord(Point center, double radius) ->
String.format("圆形 - 中心(%d, %d), 半径%.1f",
center.x(), center.y(), radius);
case String s ->
"字符串: " + s;
case Integer i ->
"整数: " + i;
case null ->
"空对象";
default ->
"未知对象: " + obj.getClass().getSimpleName();
};
}
性能优势:
适用场景:
特性说明:
核心接口:
SequencedCollection:有序集合的基本接口SequencedSet:有序集合的子接口,添加了Set特性SequencedMap:有序映射的接口核心方法:
getFirst():获取第一个元素getLast():获取最后一个元素addFirst():在开头添加元素addLast():在结尾添加元素removeFirst():移除第一个元素removeLast():移除最后一个元素reversed():获取反转视图putFirst():在映射开头添加键值对putLast():在映射结尾添加键值对firstEntry():获取第一个键值对lastEntry():获取最后一个键值对代码示例:
public static void demonstrateSequencedCollections() {
System.out.println("n=== 有序集合示例 ===");
// SequencedSet
System.out.println("--- SequencedSet ---");
SequencedSet<String> sequencedSet = new LinkedHashSet<>();
sequencedSet.addAll(List.of("A", "B", "C", "D"));
System.out.println("原始顺序: " + sequencedSet);
System.out.println("第一个元素: " + sequencedSet.getFirst());
System.out.println("最后一个元素: " + sequencedSet.getLast());
System.out.println("反转视图: " + sequencedSet.reversed());
// SequencedMap
System.out.println("n--- SequencedMap ---");
SequencedMap<Integer, String> sequencedMap = new LinkedHashMap<>();
sequencedMap.put(1, "一");
sequencedMap.put(2, "二");
sequencedMap.put(3, "三");
System.out.println("原始顺序: " + sequencedMap);
System.out.println("第一个条目: " + sequencedMap.firstEntry());
System.out.println("最后一个条目: " + sequencedMap.lastEntry());
System.out.println("反转视图: " + sequencedMap.reversed());
// 在开头和结尾操作
sequencedMap.putFirst(0, "零");
sequencedMap.putLast(4, "四");
System.out.println("操作后: " + sequencedMap);
}
性能优势:
适用场景:
| 特性 | 性能提升 | 适用场景 |
|---|---|---|
| 虚拟线程 | 创建和启动速度比传统线程快100倍以上,内存占用低100-1000倍 | IO密集型应用、高并发Web服务器 |
| 记录模式 | 减少了记录类字段访问的样板代码,编译器可进行更积极的优化 | 处理记录类、复杂数据结构解构 |
| 有序集合 | 提供了高效的首尾元素访问和操作,统一了API | 需要频繁访问首尾元素的场景 |
| 模式匹配for循环 | 减少了样板代码,提高了代码可读性 | 集合元素处理 |
| 字符串模板 | 减少了字符串拼接的样板代码 | 字符串格式化 |
| 向量API | 支持SIMD操作,提高数值计算性能 | 科学计算、图像处理、机器学习 |
Executors.newVirtualThreadPerTaskExecutor()创建虚拟线程执行器getFirst()、getLast()等方法访问首尾元素reversed()方法获取反转视图addFirst()、addLast()等方法在首尾添加元素package com.java.learning;
import java.util.*;
import java.util.concurrent.*;
import java.time.*;
public class JDK21Features {
public static void main(String[] args) throws Exception {
demonstrateVirtualThreads();
demonstrateRecordPatterns();
demonstrateSequencedCollections();
}
public static void demonstrateVirtualThreads() throws Exception {
System.out.println("=== 虚拟线程示例 ===");
// 创建虚拟线程的几种方式
System.out.println("1. 使用Thread.startVirtualThread");
Thread virtualThread1 = Thread.startVirtualThread(() -> {
System.out.println("虚拟线程执行: " + Thread.currentThread());
});
virtualThread1.join();
System.out.println("n2. 使用Thread.ofVirtual()");
Thread virtualThread2 = Thread.ofVirtual()
.name("my-virtual-thread-", 0)
.start(() -> {
System.out.println("命名的虚拟线程: " + Thread.currentThread().getName());
});
virtualThread2.join();
System.out.println("n3. 使用Executors.newVirtualThreadPerTaskExecutor");
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
List<Future<String>> futures = new ArrayList<>();
for (int i = 1; i <= 5; i++) {
final int taskId = i;
Future<String> future = executor.submit(() -> {
Thread.sleep(100); // 模拟IO操作
return "任务 " + taskId + " 完成 by " + Thread.currentThread();
});
futures.add(future);
}
// 获取结果
for (Future<String> future : futures) {
System.out.println(future.get());
}
}
// 演示虚拟线程的轻量级特性
System.out.println("n4. 创建大量虚拟线程");
long startTime = System.currentTimeMillis();
int numberOfThreads = 10000;
CountDownLatch latch = new CountDownLatch(numberOfThreads);
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
for (int i = 0; i < numberOfThreads; i++) {
final int threadId = i;
executor.submit(() -> {
try {
Thread.sleep(100); // 模拟IO等待
System.out.print(".");
if (threadId % 1000 == 0) {
System.out.println(" [" + threadId + "]");
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} finally {
latch.countDown();
}
});
}
latch.await(); // 等待所有任务完成
}
long endTime = System.currentTimeMillis();
System.out.println("n创建 " + numberOfThreads + " 个虚拟线程耗时: " +
(endTime - startTime) + "ms");
}
public static void demonstrateRecordPatterns() {
System.out.println("n=== 记录模式示例 ===");
List<Object> objects = Arrays.asList(
new Point(10, 20),
new CircleRecord(new Point(5, 5), 8.0),
"Just a string",
42
);
for (Object obj : objects) {
String description = processObject(obj);
System.out.println(description);
}
// 嵌套记录模式
System.out.println("n--- 嵌套记录模式 ---");
RectangleRecord rect = new RectangleRecord(
new Position(new Point(0, 0)),
new Position(new Point(10, 10))
);
if (rect instanceof RectangleRecord(Position(Point upperLeft), Position(Point lowerRight))) {
System.out.println("矩形: 左上角(" + upperLeft.x() + "," + upperLeft.y() +
"), 右下角(" + lowerRight.x() + "," + lowerRight.y() + ")");
}
}
private static String processObject(Object obj) {
// 记录模式在switch中的使用
return switch (obj) {
case Point(int x, int y) ->
String.format("点坐标: (%d, %d)", x, y);
case CircleRecord(Point center, double radius) ->
String.format("圆形 - 中心(%d, %d), 半径%.1f",
center.x(), center.y(), radius);
case String s ->
"字符串: " + s;
case Integer i ->
"整数: " + i;
case null ->
"空对象";
default ->
"未知对象: " + obj.getClass().getSimpleName();
};
}
public static void demonstrateSequencedCollections() {
System.out.println("n=== 有序集合示例 ===");
// SequencedSet
System.out.println("--- SequencedSet ---");
SequencedSet<String> sequencedSet = new LinkedHashSet<>();
sequencedSet.addAll(List.of("A", "B", "C", "D"));
System.out.println("原始顺序: " + sequencedSet);
System.out.println("第一个元素: " + sequencedSet.getFirst());
System.out.println("最后一个元素: " + sequencedSet.getLast());
System.out.println("反转视图: " + sequencedSet.reversed());
// SequencedMap
System.out.println("n--- SequencedMap ---");
SequencedMap<Integer, String> sequencedMap = new LinkedHashMap<>();
sequencedMap.put(1, "一");
sequencedMap.put(2, "二");
sequencedMap.put(3, "三");
System.out.println("原始顺序: " + sequencedMap);
System.out.println("第一个条目: " + sequencedMap.firstEntry());
System.out.println("最后一个条目: " + sequencedMap.lastEntry());
System.out.println("反转视图: " + sequencedMap.reversed());
// 在开头和结尾操作
sequencedMap.putFirst(0, "零");
sequencedMap.putLast(4, "四");
System.out.println("操作后: " + sequencedMap);
}
}
// 记录类定义
record Point(int x, int y) {
public double distanceTo(Point other) {
int dx = x - other.x;
int dy = y - other.y;
return Math.sqrt(dx * dx + dy * dy);
}
}
record CircleRecord(Point center, double radius) {
public double area() {
return Math.PI * radius * radius;
}
}
record Position(Point point) {
// 包装类示例
}
record RectangleRecord(Position upperLeft, Position lowerRight) {
public double width() {
return Math.abs(lowerRight.point().x() - upperLeft.point().x());
}
public double height() {
return Math.abs(lowerRight.point().y() - upperLeft.point().y());
}
public double area() {
return width() * height();
}
}
JDK 21作为长期支持(LTS)版本,引入了多项重要特性和性能改进,为Java开发者带来了更好的开发体验和性能表现。从虚拟线程到记录模式,从有序集合到字符串模板,这些特性不仅使代码更简洁、更易读,还显著提升了应用程序的性能。
通过合理使用JDK 21的新特性,开发者可以:
JDK 21的发布标志着Java平台的持续演进,为Java在现代应用开发中保持竞争力奠定了基础。对于企业应用和长期项目,升级到JDK 21可以获得更好的性能、更丰富的功能和更长的支持周期,是一个值得考虑的选择。
此外,JDK 21中的预览特性也为未来版本的发展指明了方向,开发者可以通过关注这些特性,为未来的Java版本做好准备,保持技术的先进性。
OpenClaw高级进阶技巧分享!模型精选策略+记忆系统优化经验+深度搜索集成+Gateway崩溃自动修复!Claude Code自动读日志修Bug重启验证
解决 OpenClaw 飞书插件 API 过度调用问题
2026-02-23
2026-02-23