Java language feature series
- New features of Java5
- New features of Java6
- New features of Java7
- New features of Java8
- New features of Java9
- What's new in Java 10
- What's new in Java 11
- New features in Java 12
- New features in Java 13
- New features in Java 14
- New features in Java 15
- New features in Java 16
- New features in Java 17
- New features in Java 18
- New features in Java 19
- New features of Java 20
sequence
This article mainly talks about the new features of Java 19
version number
java -version
openjdk version "19" 2022-09-20
OpenJDK Runtime Environment (build 19+36-2238)
OpenJDK 64-Bit Server VM (build 19+36-2238, mixed mode, sharing)
It can be seen from the version information that it is build 19+36
Feature list
JEP 405: Record Patterns (Preview)
The pattern matching of instanceof is used as a preview in JDK14, in JDK15 as the second round preview, and in JDK16 JEP 394: Pattern Matching for instanceof becomes positive
switch pattern matching was introduced in JDK17's JEP 406: Pattern Matching for switch (Preview) as the preview version, and in JDK18's JEP 420: Pattern Matching for switch (Second Preview) as the second round of preview
For the record type, the introduction of instance of can be written like this
record Point(int x, int y) {}
static void printSum(Object o) {
if (o instanceof Point p) {
int x = p.x();
int y = p.y();
System.out.println(x+y);
}
}
Now you can write
record Point(int x, int y) {}
void printSum(Object o) {
if (o instanceof Point(int x, int y)) {
System.out.println(x+y);
}
}
More complex example:
record Point(int x, int y) {}
enum Color { RED, GREEN, BLUE }
record ColoredPoint(Point p, Color c) {}
record Rectangle(ColoredPoint upperLeft, ColoredPoint lowerRight) {}
Rectangle r = new Rectangle(new ColoredPoint(new Point(x1, y1), c1),
new ColoredPoint(new Point(x2, y2), c2));
static void printXCoordOfUpperLeftPointWithPatterns(Rectangle r) {
if (r instanceof Rectangle(ColoredPoint(Point(var x, var y), var c),
var lr)) {
System.out.println("Upper-left corner: " + x);
}
}
If it is a generic record:
record Box<T>(T t) {}
static void test1(Box<Object> bo) {
if (bo instanceof Box<Object>(String s)) {
System.out.println("String " + s);
}
}
static void test2(Box<Object> bo) {
if (bo instanceof Box<String>(var s)) {
System.out.println("String " + s);
}
}
JEP 422: Linux/RISC-V Port
RISC-V is an open source instruction set architecture (ISA) based on the principle of reduced instruction set (RISC), and this JEP transplants JDK to RISC-V
JEP 424: Foreign Function & Memory API (Preview)
The Foreign Function & Memory (FFM) API includes two incubation APIs
JEP 370: Foreign-Memory Access API (Incubator) of JDK14 introduces the Foreign-Memory Access API as an incubator
JDK15's JEP 383: Foreign-Memory Access API (Second Incubator) Foreign-Memory Access API as a second-round incubator
JDK16's JEP 393: Foreign-Memory Access API (Third Incubator) As the third round, it introduces the Foreign Linker API (JEP 389 )
The FFM API was introduced as an incubator in JDK 17's JEP 412: Foreign Function & Memory API (Incubator)
FFM API in JDK 18's JEP 419: Foreign Function & Memory API (Second Incubator) as a second round incubator
This JEP of JDK19 uses the FFM API as the preview API
Example of use
// 1. Find foreign function on the C library path
Linker linker = Linker.nativeLinker();
SymbolLookup stdlib = linker.defaultLookup();
MethodHandle radixSort = linker.downcallHandle(
stdlib.lookup("radixsort"), ...);
// 2. Allocate on-heap memory to store four strings
String[] javaStrings = { "mouse", "cat", "dog", "car" };
// 3. Allocate off-heap memory to store four pointers
SegmentAllocator allocator = SegmentAllocator.implicitAllocator();
MemorySegment offHeap = allocator.allocateArray(ValueLayout.ADDRESS, javaStrings.length);
// 4. Copy the strings from on-heap to off-heap
for (int i = 0; i < javaStrings.length; i++) {
// Allocate a string off-heap, then store a pointer to it
MemorySegment cString = allocator.allocateUtf8String(javaStrings[i]);
offHeap.setAtIndex(ValueLayout.ADDRESS, i, cString);
}
// 5. Sort the off-heap data by calling the foreign function
radixSort.invoke(offHeap, javaStrings.length, MemoryAddress.NULL, '\0');
// 6. Copy the (reordered) strings from off-heap to on-heap
for (int i = 0; i < javaStrings.length; i++) {
MemoryAddress cStringPtr = offHeap.getAtIndex(ValueLayout.ADDRESS, i);
javaStrings[i] = cStringPtr.getUtf8String(0);
}
assert Arrays.equals(javaStrings, new String[] {"car", "cat", "dog", "mouse"}); // true
JEP 425: Virtual Threads (Preview)
Virtual threads should be the most important feature of JDK19. The first integration is the API of preview
Virtual threads are user-mode threads provided by JDK, similar to goroutines in golang and processes in erlang
The virtual thread adopts the M:N scheduling mode, that is, M number of virtual threads run on N Threads, using ForkJoinPool to schedule in FIFO mode, N is Runtime.availableProcessors() by default, you can passjdk.virtualThreadScheduler.parallelism
to modify
Example of use
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
As above, a few OS threads are used to run 10,000 virtual threads. Virtual threads can significantly improve the throughput of the system in more than a thousand non-CPU-intensive concurrent task scenarios.
void handle(Request request, Response response) {
var url1 = ...
var url2 = ...
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
var future1 = executor.submit(() -> fetchURL(url1));
var future2 = executor.submit(() -> fetchURL(url2));
response.send(future1.get() + future2.get());
} catch (ExecutionException | InterruptedException e) {
response.fail(e);
}
}
String fetchURL(URL url) throws IOException {
try (var in = url.openStream()) {
return new String(in.readAllBytes(), StandardCharsets.UTF_8);
}
}
Although this scenario is block code, because virtual threads are introduced, the system can scale well; when virtual threads are blocked in IO or other operations (BlockingQueue.take()
), virtual threads will be removed from Thread unmount, when the operation is completed, remount it to continue execution. However, some operations will not unmount the virtual thread, and will block together with the thread and the underlying OS thread (such as entering a synchronized code block/method, such as executing a native method or foreign function).
The overhead of virtual threads is not large, so there is no need to use pooling technology to usejcmd <pid> Thread.dump_to_file -format=json <file>
You can dump virtual threads in json format, examples are as follows
Thread.Builder, Thread.ofVirtual(), Thread.ofPlatform() can be used to create virtual threads or platform threads, such as
Thread thread = Thread.ofVirtual().name("duke").unstarted(runnable);
Thread.startVirtualThread(Runnable)
Equivalent to creating and starting a virtual thread
Thread.threadId() as a final method returns the thread ID, while non-final Thread.getId() is deprecated
Thread.getAllStackTraces() now returns platform threads instead of all threads
JEP 426: Vector API (Fourth Incubator)
JDK16 introduced JEP 338: Vector API (Incubator) provides jdk.incubator.vector for vector computation
JDK17 improves and serves as the second round of incubator JEP 414: Vector API (Second Incubator)
JDK18's JEP 417: Vector API (Third Incubator) is improved and used as the third-round incubator, while JDK19 is used as the fourth-round incubator
JEP 427: Pattern Matching for switch (Third Preview)
The pattern matching of instanceof is used as a preview in JDK14, as a second-round preview in JDK15, and positive in JDK16
JDK17 introduces JEP 406: Pattern Matching for switch (Preview)
JEP 420: Pattern Matching for switch (Second Preview) of JDK18 is used as the second round preview, and JDK19 is used as the third round preview
JEP 428: Structured Concurrency (Incubator)
Structured concurrency is also an important feature of JDK19. ExecutorService introduced by JDK5 can be used to process tasks in parallel, such as
Response handle() throws ExecutionException, InterruptedException {
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);
}
But when findUser throws an exception, fetchOrder will continue to run in its own thread, or findUser needs to run for a long time, and when fetchOrder is abnormal, the entire handle method still needs to waste time waiting for findUser to finish executing, it blocks in user.get ( ). In order to better handle the cancellation of other subtasks in abnormal scenarios, structured concurrency is introduced to solve this problem, mainly the StructuredTaskScope class, which can fork subtasks and then join or cancel together.
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());
}
}
If one of the subtasks fails, the other running task is canceled. After scope.join(), you can use resultNow() or exceptionNow() to get the result
Detailed Interpretation
Listed above are major features, in addition to some API updates and discards, mainly see JDK 19 Release Notes , here are a few examples.
Add item
System Properties for System.out and System.err ( JDK-8283620 )
Added stdout.encoding these two system properties stderr.encoding
Support Unicode 14.0 ( JDK-8268081 )
Added support for unicode version 14.0
Additional Date-Time Formats ( JDK-8176706 )
In the past, java.time.format.DateTimeFormatter/DateTimeFormatterBuilder only supported four kinds of FormatStyle.FULL/LONG/MEDIUM/SHORT. Now it can be customized, such as
DateTimeFormatter.ofLocalizedPattern("yMMM")
Automatic Generation of the CDS Archive ( JDK-8261455 )
Added
-XX:+AutoCreateSharedArchive
parameter can automatically create CDS archive, such asjava -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=app.jsa -cp app.jar App
remove item
Remove Finalizer Implementation in SSLSocketImpl ( JDK-8212136 )
Remove finalizer implementation of SSLSocket
Removal of Diagnostic Flag GCParallelVerificationEnabled ( JDK-8286304 )
Remove GCParallelVerificationEnabled parameter
obsolete
For a complete list see Java SE 19 deprecated-list
java.lang.ThreadGroup Is degraded ( JDK-8284161 )
ThreadGroup can no longer be shown destroyed, it now no longer holds a strong reference to its subgroup
Deprecation of Locale Class Constructors ( JDK-8282819 )
The Locale constructor is deprecated and can be replaced by the Locale.of() factory method
Known Issues
ForkJoinPool and ThreadPoolExecutor do not use Thread::start to Start Worker Threads ( JDK-8284161 )
ForkJoinPool and ThreadPoolExecutor no longer use `Thread::start to start threads in this version, so those worker threads that override start without parameters may be affected, but ForkJoinWorkerThread.onStart() is not affected
InflaterInputStream.read Throws EOFException ( JDK-8292327 )
InflaterInputStream may throw EOFException in this version
G1 Remembered set memory footprint regression after JDK-8286115 ( JDK-8292654 )
JDK-8286115, which changes the ergonomic size of G1's RSet, will increase local memory usage, which can be alleviated by increasing the value of G1RemSetArrayOfCardsEntries, such as
-XX:+UnlockExperimentalVMOptions -XX:G1RemSetArrayOfCardsEntries=128
something else
JNI GetVersion Returns JNI_VERSION_19 ( JDK-8286176 )
The jni method GetVersion returns JNI_VERSION_19
Double.toString(double) and Float.toString(float) may Return Slightly Different Results ( JDK-4511638 )
Double.toString(2e23), now returns "2.0E23", whereas previous versions returned "1.9999999999999998E23"
Make HttpURLConnection Default Keep Alive Timeout Configurable ( JDK-8278067 )
Added http.keepAlive.time.server and http.keepAlive.time.proxy system properties that can be used to modify the default Keep Alive Timeout
JVM TI Changes to Support Virtual Threads ( JDK-8284161 )
The JVM Tool Interface (JVM TI) has been updated to support virtual threads
-Xss may be Rounded up to a Multiple of the System Page Size ( JDK-8236569 )
The actual java thread stack size may differ from the value specified by the -Xss command line option; it may be rounded to a multiple of the page size required by the system.
summary
Java18 mainly has the following features
- JEP 405: Record Patterns (Preview)
- JEP 422: Linux/RISC-V Port
- JEP 424: Foreign Function & Memory API (Preview)
- JEP 425: Virtual Threads (Preview)
- JEP 426: Vector API (Fourth Incubator)
- JEP 427: Pattern Matching for switch (Third Preview)
- JEP 428: Structured Concurrency (Incubator)
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。