2. Contact
Vadym Kazulkin
ip.labs GmbH Bonn, Germany
Co-Organizer of the Java User Group Bonn
v.kazulkin@gmail.com
@VKazulkin
https://www.linkedin.com/in/vadymkazulkin
https://www.iplabs.de/
7. Project Valhalla
(Initial) Goal:
Reboot the layout of data in memory
Source: Brian Goetz „State of Valhalla Part 1: The Road to Valhalla”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/01-background
12. Project Valhalla
Storing objects in the Java Heap has its price, because storing
object’s metadata consumes additional memory for :
• flags facilitating synchronization/locking
• Identity and polymorphismus
• garbage collection
14. Project Valhalla
Value Types
Immutable: an instance of a value type can’t change, once it’s been
created
Identity-less: value types of the same type with the same contents
are indistinguishable from each other
Flattenable: JVMs are allowed to flatten a value type inside of its
container
Source: Brian Goetz „State of Valhalla Part 1: The Road to Valhalla”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/01-background
15. Project Valhalla
Source: Brian Goetz „State of Valhalla Part 1: The Road to Valhalla”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/01-background
Memory layout of XY Points Flattened memory layout of XY
Points in case of Value Type
16. Project Valhalla
Benefits:
• Reduced memory usage
• Reduced indirection
• Increased locality
Codes like a class, works like a primitive
(Brian Goetz)
17. Project Valhalla
Benefit: Reduced Memory Usage
No additional memory to store object metadata, such as
flags facilitating synchronization, identity, polymorphism and
garbage collection
18. Project Valhalla
Benefit: Reduced indirection
Since objects are stored as reference types in Java, each time
an object is accessed it must first be dereferenced, causing
additional instructions to be executed
The flattened data associated with value types are
immediately present in the location in which they are needed
and therefore, require no dereferencing
19. Project Valhalla
Benefit: Increased locality
Flattened value objects remove indirection which increases
the likelihood that values are adjacently stored in memory–
especially for arrays or other contiguous memory structures
such as classes (i.e. if a class contains value type fields)
Increases the chance of cache hits, because of hardware
prefetch of the cache lines
21. Project Valhalla
Value Types
Can
• have method and field (implicitly final)
• implement interfaces
• extend “well-formed” abstract class
• no fields
• empty no-arg constructor
• no synchronized methods
• use encapsulation
• be generic
Can’t
• be mutated
• be sub-classed (value class is final)
• be cloned
• be Enums
• be used synchronization (IllegalMonitorStateException)
• be null *
Source: Brian Goetz „State of Valhalla Part 2: The Language Model”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/02-object-model
22. Project Valhalla
Types Hierarchy
Object
ValueObject
Value Types
2 new interfaces IdentityObject
Reference Types
Source: Brian Goetz „State of Valhalla Part 2: The Language Model”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/02-object-model
24. Project Valhalla
Reference and Value Projection
value class V {} our code
sealed abstract class V.ref permits V.val {}
will be generated
value class V.val extends V.ref {}
V – value type
V.ref - reference projection for V
V.val - value projection for V
Source: Sergej Kuksenko „Valhalla is coming“ https://www.youtube.com/watch?v=ri5i3mnSNk8
25. Existing Java Classes as Value Types
• Primitive Wrappers (like java.lang.Integer)
• have identity, but not only is this identity not directly useful, it can
be a source of bugs. For example, due to caching, Integers can be
accidentally compared correctly with == .
• java.util.Optional
• java.time.LocalDateTime
Source: https://docs.oracle.com/javase/8/docs/api/java/lang/doc-files/ValueBased.html
26. Project Valhalla
Migrations of existing code
Map <K,V> V get (Object key)
Returns the value to which the specified key is mapped, or null if this map
contains no mapping for the key.
-> Map <K,V> V.ref get (Object key)
Optional <T> o;
o=null;
-> reference projection of Optional will be used by default. Rewrite
your code to use value projection for Optional with value classes
Source: Sergej Kuksenko „Valhalla is coming“ https://www.youtube.com/watch?v=ri5i3mnSNk8
27. Project Valhalla
Types Hierarchy
Object
ValueObject
Value Types
2 new interfaces IdentityObject
Reference Types
Primitive
types
Source: Brian Goetz „State of Valhalla Part 2: The Language Model”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/02-object-model
28. Project Valhalla
Primitive Types
primitive class Point implements Serializable {
private int x;
private int y;
….
}
A primitive class is a special value class whose instances can be represented as
values of a primitive type.
• The name of the class (Point) is also the name of the primitive type.
• Users of the primitive type can expect familiar primitive semantics and performance
— for example, the primitive type cannot be null.
A primitive class declaration is subject to the same constraints as value class
declarations
• the instance fields are implicitly final
• primitive type circularities in instance field types are not allowed—flattened instances
must not contain other instances of the same type.
Source: Brian Goetz „State of Valhalla Part 2: The Language Model”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/02-object-model
29. Project Valhalla
Migrations of existing code
Primitive Wrappers like Integer can be considered as value class
Primitives like int will be replaced by the primitive class int {….}
Integer == int.ref
Integer.val==int
Benefits:
• Java becomes true OOP language
• Full covariant arrays : int[] <: Integer [] <: Object []
• Future support of Specialized Generics List<int> will become easier
Source: Brian Goetz „State of Valhalla Part 2: The Language Model”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/02-object-model
30. Project Valhalla
Identity classes vs value classes vs primitives
• Use identity classes when we need mutability, layout extension, or
locking
• Consider value classes when we don’t need identity, but need
nullity or have cross-field invariants
• Consider primitive classes when we don’t need identity, nullity, or
cross-field invariants, and can tolerate the zero default that comes
with primitives
• Remember that the P.ref reference type for a primitive recovers the
benefits of a value class.
Source: Brian Goetz „State of Valhalla Part 2: The Language Model”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/02-object-model
31. Project Valhalla
Migrations of the primitives and universal generics JEPs
Source: https://openjdk.java.net/jeps/401, https://openjdk.java.net/jeps/402, https://openjdk.org/jeps/8261529
32. Project Valhalla
(Initial) Goal:
Reboot the layout of data in memory
shifts to
Unify the Java type system
Source: Brian Goetz „State of Valhalla Part 2: The Language Model”
https://openjdk.org/projects/valhalla/design-notes/state-of-valhalla/02-object-model
33. Project Value classes vs Records
• A record requires you to give up on extension, mutability, and the ability to
decouple the representation from the API.
• In return, you get implementations of constructors, accessors and identity-based
equals and hashCode
• Value class requires you to give up on identity, which includes giving up on
extension and mutability, as well as some other things (e.g., synchronization).
• In return, you get a different set of benefits: flattened representation, optimized
calling sequences, and state-based equals and hashCode.
Source: https://stackoverflow.com/questions/63352151/are-java-records-intended-to-
eventually-become-value-types
36. Project Loom
Motivation:
Developers currently have 2 choices to write concurrent
code:
• use blocking/synchronous API, which is simple, but less scalable (number of
threads, that OS supports is far less that open and concurrent connections
required)
• asynchronous API (Spring Project Reactor, RXJava 2), which is scalable, but
complex, harder to debug and profile and limited (no asynchronous JDBC
standard in this area)
Sources: Alan Bateman, Oracle „Project Loom: Fibers and Continuations for Java”
https://www.youtube.com/watch?v=vbGbXUjlRyQ
38. Project Loom
Lightweight Thread
Virtual thread scheduled not by the OS, but by the Java Runtime
with low memory footprint and low task-switching cost
Sources: https://inside.java/2020/07/29/loom-accentodev/
40. Continuation
package java.lang;
public class Continuation {
public Continuation (ContinuationScope scope, Runnable target)
public final void run()
public static void yield (ContinuationScope scope)
public boolean isDone()
}
41. Project Loom
Continuations
example () {
var scope = new ContinuationScope(„Example_Scope“);
var continuation = new Continuation (scope, () -> {
out.print(„1“);
Continuation.yield(scope);
out.print(„2“);
Continuation.yield(scope);
out.print(„3“);
Continuation.yield(scope);
});
while (! continuation.isDone()) {
out.print(„ run.. “);
continuation.run();
}
}
Output: run.. 1 run.. 2 run.. 3
43. Project Loom
Schedular
Schedular executes the task on a pool of carrier threads
java.util.concurrent.Executor API exposes the Schedular
Default schedular is a ForJoinPool
Source: Alan Bateman, Oracle „Project Loom Update” https://www.youtube.com/watch?v=NV46KFV1m-4
44. Project Loom
Virtual Thread Implementation
Thread and Virtual Thread don’t have a common supertype
Thread.currentThread() in context of Virtual Thread
• Creates adaptor (Shadow Thread)
• Adaptor emulates legacy Thread API (except deprecated methods like stop,
suspend and resume)
• Thread Local becomes Virtual Thread Local
Source: Alan Bateman, Oracle „Project Loom Update” https://www.youtube.com/watch?v=NV46KFV1m-4
45. Project Loom
Virtual Thread Implementation
Thread t = Thread.startVirtualThread (() -> {
System.out.println(„Hello World“);
});
Thread t = Thread.builder().virtual().task( () -> { … }).build();
Thread t = Thread.builder().virtual().task( () -> { … }).start();
ThreadFactory factory = Thread.builder().virtual().factory();
Source: Ron Pressler: “Project Loom: Modern Scalable Concurrency for the Java”
https://www.youtube.com/watch?v=23HjZBOIshY
https://cr.openjdk.java.net/~rpressler/loom/loom/
46. Project Loom
Structured Concurrency
Basic idea: Everytime that the control splits into multiple
concurrent paths, we want to guarantee that they join up again
try (var executor= Executors.newVirtualThreadExecutor()) {
executor.submit(task1);
executor.submit(task2);
} //blocks until task1 and task2 terminate
Sources: Nathanial J. Smith „Notes on structured concurrency, or: Go statement considered harmful”
https://vorpus.org/blog/notes-on-structured-concurrency-or-go-statement-considered-harmful/
R. Elizarov: “Structured concurrency with Coroutines in Kotlin” https://medium.com/@elizarov/structured-concurrency-
722d765aa952
47. Project Loom
Structured Concurrency
Cancelation :
We can also give all tasks a deadline that will interrupt those children
that have yet to terminate by the time it expires (as well as the current
thread)
try (var executor= Executors.newVirtualThreadExecutor().
withDeadline(Instant.now().plusSeconds(60))) {
executor.submit(task1);
executor.submit(task2);
}
Source: Ron Pressler: “Project Loom: Modern Scalable Concurrency for the Java Platform”
https://www.youtube.com/watch?v=EO9oMiL1fFo https://cr.openjdk.java.net/~rpressler/loom/loom/
48. Project Loom
JEP 428 Structured Concurrency JEP
Sources: „Structured Concurrency“ https://openjdk.org/jeps/428
49. Project Loom
StructuredTaskScope Class
Sources: StructuredTaskScope Class
https://download.java.net/java/early_access/loom/docs/api/jdk.incubator.concurrent/jdk/incubator/concurrent/StructuredTask
Scope.html
50. Project Loom
Structured Executor Example
Sources: „Structured Concurrency (Preview)“ https://openjdk.java.net/jeps/8277129
Response handle() throws ExecutionException,
InterruptedException {
try (var scope = new StructuredTaskScope.ShutdownOnFailure()) {
Future<String> user = s.fork(() -> findUser());
Future<Integer> order = s.fork(() -> fetchOrder());
scope.join(); //join both forks
scope.throwIfFailed();
// Here, both forks have succeeded, so compose their results
return new Response(user.resultNow() + order.resultNow());
}
51. Project Loom
Virtual Thread
Current Status:
Virtual Thread supports:
• scheduling
• parking/unparking
• waiting for a Virtual Thread to terminate
• Java Flight Recorder support
Virtual Thread -friendly APIs changes
• java.util.concurrent Locks
• java.io.Console, Reader, Writer Buffered/File/Piped I/O Streams, File
• Java.util.concurrent Executors, SynchronousQueue,
• java.net.Socket/ServerSocket/InetAdress (
• java.nio.channels.SocketChannel and Pipes
• Thread.sleep
• JSSE implementation of TLS
• AccessControl.doPrivileged
Source: Ron Pressler, Project Loom: Helping Write Concurrent Applications on the Java Platform
https://www.youtube.com/watch?v=lIq-x_iI-kc
52. Project Loom
Current Status:
In Preview for JDK 19 :
javac --release 19 --enable-preview --add-modules
jdk.incubator.concurrent YourClass.java
java --enable-preview --add-modules jdk.incubator.concurrent
YourClass
Source: „JEP 428: Structured Concurrency to Simplify Java Multithreaded Programming “
https://www.infoq.com/news/2022/06/java-structured-concurrency/
53. Project Loom
• Since Java 5 and 6 developers and library creators are
encouraged to use Executors and ThreadFactory APIs
instead of Thread directly
• In order to use Virtual Thread instead of Thread
another Executor implementation must be chosen or
be configurable
ThreadFactory factory =
Thread.builder().virtual().factory();
Executor executor=
Executors.newVirtualThreadExecutor(factory);