JDK 9
模块系统(Project Jigsaw):
定义模块:
复制代码
module my.module {
requires java.base; // 依赖模块
exports my.package; // 公开包
}
使用模块:
在 module-info.java 文件中声明模块依赖和导出包。
JShell:
使用 JShell:
运行 jshell 命令进入交互式环境,可以直接输入和执行 Java 代码。
$ jshell
jshell> String greeting = "Hello, World!";
jshell> System.out.println(greeting);
增强的 Stream API:
新方法:
// takeWhile 和 dropWhile 示例
List<String> list = Arrays.asList("a", "b", "c");
list.stream().takeWhile(s -> s.equals("a")).forEach(System.out::println); // 输出 "a"
@SafeVarargs 注解:
示例:
@SafeVarargs
public final <T> void print(T... args) {
for (T arg : args) {
System.out.println(arg);
}
}
改进的 Process API:
使用 ProcessHandle:
ProcessHandle handle = ProcessHandle.current();
System.out.println("PID: " + handle.pid());
JDK 10
局部变量类型推断(var):
示例:
var list = new ArrayList<String>(); // 类型推断为 ArrayList<String>
var stream = list.stream(); // 类型推断为 Stream<String>
应用类数据共享(AppCDS):
使用 AppCDS:
$ java -Xshare:dump -XX:SharedArchiveFile=app-cds.jsa -jar myapp.jar
$ java -Xshare:on -XX:SharedArchiveFile=app-cds.jsa -jar myapp.jar
增强的 G1 垃圾回收器:
使用:
-XX:+UseG1GC
JDK 11
HttpClient API:
示例:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder(URI.create("https://example.com")).build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
字符串处理改进:
示例:
复制代码
String str = " Hello ";
System.out.println(str.strip()); // "Hello"
System.out.println(str.isBlank()); // false
ZGC (Z Garbage Collector):
使用:
```shell
-XX:+UseZGC
移除 Java EE 和 CORBA 模块:
影响:
相关的模块和 API 不再包含在 JDK 中,需要依赖第三方库。
JDK 12
Switch 表达式(预览):
示例:
String dayType = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> "Weekend";
case TUESDAY, WEDNESDAY, THURSDAY -> "Weekday";
default -> throw new IllegalArgumentException("Invalid day: " + day);
};
JVM 常量 API:
示例:
ConstantDesc constantDesc = MethodHandles.constant(String.class, "constantValue");
JDK 13
文本块(预览):
示例:
String json = """
{
"name": "John",
"age": 30
}
""";
switch 表达式(进一步改进):
改进:
进一步修复和优化 switch 表达式的行为。
JDK 14
记录类型(预览):
示例:
public record Person(String name, int age) {}
Person p = new Person("Alice", 30);
System.out.println(p.name()); // "Alice"
null 处理改进(NVM):
改进:
提供了更详细的 NullPointerException 堆栈跟踪。
JDK 15
sealed 类(预览):
示例:
public sealed class Shape permits Circle, Rectangle {}
public final class Circle extends Shape {}
public final class Rectangle extends Shape {}
文本块(标准化):
正式特性:
文本块成为正式特性,继续使用原有语法。
JDK 16
record 类(标准化):
正式特性:
记录类成为正式特性,语法和用法保持不变。
sealed 类(标准化):
正式特性:
sealed 类成为正式特性,语法和用法保持不变。
JDK 17
封闭类(正式):
正式特性:
封闭类(sealed)成为正式特性。
模式匹配 for instanceof(预览):
示例:
if (obj instanceof String s) {
System.out.println(s.toUpperCase());
}
增强的 Switch 表达式:
改进:
对 switch 表达式的模式匹配进行改进。
JDK 18
final 类方法支持:
示例:
public final class MyClass {
public final void myMethod() {
// Implementation
}
}
新的 UTF-8 编码:
影响:
UTF-8 成为默认字符编码。
JDK 19
项目 Loom(预览):
虚拟线程示例:
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
executor.submit(() -> {
// 任务代码
}).get();
}
项目 Panama(预览):
本地代码接口:
项目 Valhalla(预览):
泛型和原始类型支持:
// 示例代码
JDK 20
项目 Loom:
虚拟线程和结构化并发:
更进一步改进虚拟线程和结构化并发的支持。
模式匹配(继续预览):
模式匹配增强:
继续增强模式匹配的功能和语法。
JDK 21
项目 Loom:
虚拟线程改进:
继续改进虚拟线程的性能和稳定性。
记录模式(预览):
示例:
record Point(int x, int y) {}
Point p = new Point(1, 2);
switch (p) {
case Point(int x, int y) -> System.out.println("Point at (" + x + ", " + y + ")");
}
模式匹配 for switch:
示例:
switch (obj) {
case String s -> System.out.println(s.toUpperCase());
case Integer i -> System.out.println(i * 2);
}
虚拟线程
虚拟线程(Virtual Threads)是 Java 19 引入的一个新特性,旨在简化并发编程,使得在处理大量并发任务时更高效、更易于使用。虚拟线程的目标是使得线程的创建和管理更加轻量,减少传统线程池中的开销,同时保留传统线程的所有特性。
基本概念
虚拟线程: 虚拟线程是一种轻量级的线程实现,可以在单个操作系统线程上并发地运行多个虚拟线程。它们旨在减少线程切换的开销和资源消耗。
平台线程: 传统的线程实现,是操作系统提供的线程。
使用虚拟线程
- 创建和启动虚拟线程
虚拟线程可以通过 Thread.ofVirtual() 工厂方法创建。以下是一个基本的示例:
public class VirtualThreadExample {
public static void main(String[] args) {
// 创建虚拟线程
Thread virtualThread = Thread.ofVirtual().start(() -> {
for (int i = 0; i < 5; i++) {
System.out.println("Virtual thread running");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
});
// 等待虚拟线程完成
try {
virtualThread.join();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
}
在这个示例中,Thread.ofVirtual().start() 方法创建并启动了一个虚拟线程。虚拟线程运行的代码块在 start() 方法中定义。
- 使用虚拟线程的 Executor
使用虚拟线程来创建一个虚拟线程池,使用 ExecutorService 来管理虚拟线程:
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
public class VirtualThreadPoolExample {
public static void main(String[] args) {
// 创建虚拟线程池
ExecutorService executor = Executors.newVirtualThreadPerTaskExecutor();
// 提交任务
for (int i = 0; i < 10; i++) {
final int taskId = i;
executor.submit(() -> {
System.out.println("Running task " + taskId + " in virtual thread");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
});
}
// 关闭虚拟线程池
executor.shutdown();
}
}
在这个示例中,Executors.newVirtualThreadPerTaskExecutor() 创建了一个虚拟线程池,每个任务在一个新的虚拟线程中运行。完成所有任务后,使用 shutdown() 方法关闭线程池。
主要特点
轻量级: 虚拟线程在系统中占用的资源更少,因此可以创建大量虚拟线程而不会对系统造成过大的负担。
非阻塞 I/O: 虚拟线程特别适合处理需要大量 I/O 操作的应用程序,例如网络服务器和数据库访问。
简单的并发编程: 使用虚拟线程可以简化并发编程模型,使得代码更易于理解和维护。
使用场景
I/O 密集型应用: 适用于需要处理大量 I/O 操作的应用,例如网络服务和数据库操作。
高并发任务: 适合需要大量并发任务的应用,例如消息队列的消费者。