SlideShare a Scribd company logo
1 of 84
Download to read offline
Project Loom - Einfachere Nebenläufigkeit in Java
Ein Thread, ist ein Thread, ist ein (virtueller) Thread.
Code Examples
Leading developer relations
& community at the
totally best
graph database
Who's talking?
Michael Hunger
Learning new things every
day
Having fun with code,
open-source, people
Java
Working with Java since
1995
Jug-Saxony
JavaChampion
Neo4j TechnoGirls
Supporting girls
to learn to code
Welcome
Java 20
Mar 21, 2023
sdk install java 20-open
openjdk 20 2023-03-21 build 20+36-2344
Why are we talking
about this ?
Concurrency ?
Parallelism?
There is a lot to do in a Java Program
Image Credit Marcus Biel / cleancodeacademy
● Process and answer requests
● Compute
● I/O: Read and write files
● Read from databases and network
● Synchronization
● Render
● Logging / Monitoring / Metrics
● Garbage collection
There is a lot to do! And limited resources
● Developer Brain
● CPU / Hyperthreading
● Memory
● I / O
● Network
● Disk
History in Java
Been There - Seen That
Java 1.1 - 1997
Green Threads
Java 1.3 - 1998
Native Threads
Java 1.5 - 2004
Thread Pools / Executors
Java 8 2014-2016
CompletableFuture
Rx-Java
Reactive Streams
Reactor
2017-2018
Java 9
Flow
Kotlin Coroutines - Stable
Java 19, 2022
JEP 425 Virtual Threads
Preview
Java 1.7 2011
ForkJoinPool
Parallel Streams
Java 20, 2023
JEP 436 Virtual Threads
2nd Preview
What is?
A Thread
A Thread
● Asynchronous Unit of Execution
● Multiple Threads running inside a Process
● One Thread at a time on a CPU
● Inside a thread - synchronous execution
● Switching - Switch/Save Registers / Invalidate Caches …
● Cheaper than process switching, HW support
● green (<1.3), platform/native, now virtual Threads
Green Threads vs. Native Threads
Green Threads
● User Level Threads
● Simulated Multithreading
● Runs on single (LW)Process / CPU
● Scheduled by VM, not OS
● Lots of HW context switching
● "slow"
● Abandoned in Java 1.3
● Management / State overhead
Native Threads
● Mapped to all HW Threads (HT)
● Limited to HW concurrency
● blocking, synchronous execution
● Since Java 1.3 (Solaris - 1.2)
● Better on I/O & context-switching
● Faster than process based concurrency
And now we have virtual Threads…
Java Concurrency looks
easier than it is
Devil is in the details
(Brian Goetz - JCP book)
Options Today
Hello Threading World
Example Code & Run
1. new Thread().start()
2. ThreadPool/Executor
3. Reactive Streams/Reactor/Akka
4. Kotlin Coroutines
5. Loom - Virtual Threads
Java Threads & Thread Pools
var t = new Thread(() -> System.out.println("Hello World"));
t.start();
t.join();
// new! Thread.Builder
var t = Thread.ofPlatform().start(
() -> System.out.println("Hello new World"));
t.join();
Thread Pools
try (var executor = Executors.newFixedThreadPool(5)) {
IntStream.range(0, 50).forEach(i -> {
executor.submit(() ->
System.out.println("Hello Platform Thread "+i+" "+Thread.currentThread())
);
});
} // executor.close()
Thread Pools
// takes a long time
try (var executor = Executors.newFixedThreadPool(10)) {
IntStream.range(0, 10_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(Duration.ofSeconds(1));
return i;
});
});
} // executor.close()
// parallel stream
IntStream.range(1,10).parallel()
.mapToObj( i -> "Hello World "+i)
.forEach(System.out::println);
Parallel Streams
// Completable Future
var cf = CompletableFuture.completedFuture("complex")
.thenApplyAsync(String::toUpperCase)
.thenCombine(
CompletableFuture.completedFuture("CODE")
.thenApplyAsync(String::toLowerCase),
(s1, s2) -> s1 + s2);
cf.join()
Completable Future
Reactive Programming
Reactive Java, Reactor, RxJava, Akka
String key = "message";
Mono<String> r = Mono.just("Hello")
.flatMap(s -> Mono.deferContextual(ctx ->
Mono.just(s + " " + ctx.get(key))))
.contextWrite(ctx -> ctx.put(key, "World"));
StepVerifier.create(r).expectNext("Hello World").verifyComplete();
Reactor Documentation
Kotlin Coroutines
Documentation
fun main() = runBlocking { // this: CoroutineScope
launch { doWorld() }
println("Hello")
}
// suspending function
suspend fun doWorld() {
delay(1000L)
println("World!")
}
Blocking vs. Non-Blocking
Blocking vs. Non-Blocking vs. Continuations
Blocking
● linear program-flow
● execute what you
wrote, easy to reason
● blocks on intensive
operations
● inefficient use of
resources
(utilized/blocked)
● classical Java Threading
Continuation
● ability to capture
computation so far and
continue later
● explicit continuations
(await, async, yield)
● implicit continuations (on
entry-points to blocking
ops)
● simpler API
● hard work is in the
implementation
● Kotlin, JS, Loom
Non-Blocking
● DSL for describing a
processing
● underlying reactive engine
● data flow
● resource efficient
● hard to reason, debug
unit-test, profile, maintain
● large complex API
● difficult to correlate
operations
● RxJava, Reactive Streams,
Akka
Concurrency & Parallelism help us make
more efficient use of existing resources
Concurrency & Parallelism (in Java)
Concurrency vs. Parallelism
Concurrency
● Ability to execute many (different) tasks
and make progress on all of them
● Seemingly simultaneously (e.g. on 1 CPU)
Parallel Concurrent Execution
● Multiple tasks are executed concurrently
(at the same time) AND
● Multiple CPUs are used to execute tasks
in parallel
● Most common today
Parallel Execution
● Utilize more than 1 CPU/Thread to
progress multiple tasks simultaneously
Parallelism
● Ability to divide and conquer a single
task into subtasks that can be executed
in parallel
source: jenkov.com
Concurrent
Parallel Execution
Parallel Concurrent Execution
CPU
Task 1
Task 2
CPU Task 1
Task 2
CPU
CPU
Task 1
Task 2
CPU
Task 3
Task 4
Parallelism
CPU
Thread 1
Thread 2
CPU
Thread 3
Thread 4
Parallel Execution Challenges
● Context Switches / Caches / Branch Predictions
● Race Conditions
● Mutable data / visibility
● Deadlocks
● Starvation
● Resource over- / underutilization
● Immutability / Ownership
● Reasoning / Debugging / Logging
● State-Management
● Execution Depedencies
Project Loom
JEP 425 / JEP 436
Image OpenJDK / Sharat Chander
JEP Process
JEP 425
1st Preview
Java 19
Sept 2022
Delivered
JEP 436
2nd Preview
Java 20
Mar 2023
Delivered
JEP Draft
Finalization
Java 21
Sept 2023
Submitted
● Thread Locals Support
● Virtual Thread API
● Thread.Builder
● VirtualThreadPoolExecutor
● Continuations impl
● StructuredConcurrency (inc.)
● StructuredConcurrency
● Scoped Variables
JEP 425/436 - Project Loom - openjdk.org/jeps/425 …/436
Goals
● Enable server applications written in the
simple thread-per-request style to
scale with near-optimal hardware
utilization.
● Enable existing code that uses the
java.lang.Thread API to adopt
virtual threads with minimal
change.
● Enable easy troubleshooting,
debugging, and profiling of virtual
threads with existing JDK tools.
Loom - Goals
Non-Goals
● It is not a goal to remove the traditional
implementation of threads, or to
silently migrate existing
applications to use virtual threads.
● It is not a goal to change the basic
concurrency model of Java.
● It is not a goal to offer a new data
parallelism construct in either the
Java language or the Java libraries. The
Stream API remains the preferred way
to process large data sets in parallel.
What's in the cup?
● Continuations internally in the JVM
● Reimplementation of Networking / IO Code in JVM
● lightweight Virtual Thread, same API as java.util.Thread
● Thread.Builder
● VirtualThreadExecutors
● Auto-Closeable Excecutors
● Structured Concurrency (StructuredTaskScope)
Java 20
● Scoped Values + their support in StructuredTaskScope
● StructuredTaskScope still incubator
What's in the boxcup?
More about
Virtual Threads
Virtual Thread
● same, stable API as traditional thread (deprecations will be removed)
● handled differently during blocking operations
● lightweight (300 bytes) like a Runnable, JVM can execute millions
● temporarily bound to a platform (carrier) thread
● on each blocking/parking operation -> Continuation yielding
● stack is copied to heap
● on resume, stack copied back and
● execution resumed on different carrier Thread
● uses a separate ForkJoinPool (FJP), to also prevent starving
-Djdk.defaultScheduler.parallelism=N
var threads =
IntStream.range(0,10).mapToObj(i ->
Thread.ofVirtual().start(() -> { // or Thread.startVirtualThread(runnable)
System.out.println("Hello Virtual Thread "+i+" "+Thread.currentThread());
})).toList();
for (Thread t : threads) {
t.join();
}
Java Virtual Threads - Builder
Hello Virtual Thread 3 VirtualThread[#10079]/runnable@ForkJoinPool-1-worker-18
Hello Virtual Thread 6 VirtualThread[#10082]/runnable@ForkJoinPool-1-worker-17
Hello Virtual Thread 1 VirtualThread[#10077]/runnable@ForkJoinPool-1-worker-16
Hello Virtual Thread 5 VirtualThread[#10081]/runnable@ForkJoinPool-1-worker-15
Hello Virtual Thread 7 VirtualThread[#10083]/runnable@ForkJoinPool-1-worker-17
Hello Virtual Thread 2 VirtualThread[#10078]/runnable@ForkJoinPool-1-worker-17
Hello Virtual Thread 4 VirtualThread[#10080]/runnable@ForkJoinPool-1-worker-17
Hello Virtual Thread 8 VirtualThread[#10084]/runnable@ForkJoinPool-1-worker-19
Hello Virtual Thread 9 VirtualThread[#10085]/runnable@ForkJoinPool-1-worker-18
Java Virtual Threads - Executor
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 100_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(java.time.Duration.ofSeconds(1));
return i; // callable, throws Exception
});
});
} // executor.close() is called implicitly, and waits
Under the Hood
New Rule:
If in doubt
Start a new virtual Thread
Example: Echo Web-Server
// java --enable-preview --source 20 LoomServer.java
// echo -n 'Hello Loom' | nc -n 127.0.0.1 2000
import java.io.*;
import java.net.*;
import java.util.concurrent.*;
public class LoomServer {
public static void main(String...args) throws IOException {
try (var ss = new ServerSocket(2000);
var pool = Executors.newVirtualThreadPerTaskExecutor()) {
while (true) {
var socket = ss.accept();
pool.execute(() -> {
try (var s = socket;
var in = s.getInputStream();
var out = s.getOutputStream()) {
byte b = -1;
while ((b = (byte)in.read()) != -1) {
out.write(b+1);
}
} catch(IOException ioe) {}
});
Under The Hood
● Virtual Threads run on (different) Platform Threads
● They use a separate Fork Join Pool
● Instead of blocking (IO, networking, sleep, synchronization) they are
yielding control
● Blocking Code in the JVM refactored to use Continuations
● Continuations move stack from Platform Thread to Heap
● Can pick up later on another thread
● Except when using addresses or native code
Example Thread.sleep()
● Thread.sleep()
○ VThread.sleepNanos()
■ VThread.doSleepNanos()
● VTread.parkNanos()
○ VThread.yieldContinuation()
■ unmount()
■ Continuation.yield()
static final ContinuationScope VTHREAD_SCOPE =
new ContinuationScope("VirtualThreads");
@ChangesCurrentThread
private boolean yieldContinuation() {
boolean notifyJvmti = notifyJvmtiEvents;
// unmount
if (notifyJvmti) notifyJvmtiUnmountBegin(false);
unmount();
try {
return Continuation.yield(VTHREAD_SCOPE);
} finally {
// re-mount
mount();
if (notifyJvmti) notifyJvmtiMountEnd(false);
}
}
private void unmount() {
// set Thread.currentThread() to return the platform thread
Thread carrier = this.carrierThread;
carrier.setCurrentThread(carrier);
// break connection to carrier thread, synchronized with interrupt
synchronized (interruptLock) {
setCarrierThread(null);
}
carrier.clearInterrupt();
}
Caveats or when does it not work?
● when stack cannot be moved to heap
● if it contains memory addresses
(synchronized) -> use ReentrantLock!
● calls c-code
● File I/O
● DNS (Windows)
● then the task stays pinned to a platform
thread
● to avoic exhaustion the FJP creates new
temporary platform threads
● can track with
-Djdk.tracePinnedThreads=full
example by A. Sundararajan
● Large pull request (#8166) touching 1333 files
● Thread.Builder, virtualThreadPerTaskExecutor
● refactor all blocking/parking code to use Continuations for Virtual Threads
○ Network I/O,
○ Locks
○ Thread.sleep
● replace c-code where possible with Java code (e.g. in Method ->
MethodHandles)
● not (yet):
○ File I/O (waiting for io_uring)
○ synchronized, due to address usage
JDK Changes
Continuations on the long way to Loom
What is?
A Continuation?
"A continuation is a callback function k that represents the
current state of the program's execution.
More precisely, the continuation k is a function of one
argument, namely the value that has been computed so far,
that returns the final value of the computation after the rest
of the program has run to completion."
A continuation
program
program
Stack Heap
program
continued
Stack Heap
Carrier
Threads
Continuation
yield
import jdk.internal.vm.Continuation;
import jdk.internal.vm.ContinuationScope;
var scope = new ContinuationScope("scope");
var c = new Continuation(scope, () -> {
System.out.println("Started");
Continuation.yield(scope);
System.out.println("Running");
Continuation.yield(scope);
System.out.println("Still running");
});
System.out.println("Start");
int i=0;
while (!c.isDone()) {
c.run();
System.out.println("Running "+i+" result "+c.isDone());
i++;
}
System.out.println("End"); Continuations in the JDK
Start
Started
Running 0 result false
Running
Running 1 result false
Still running
Running 2 result true
End
Structured
Concurrency?!?
JEP 428 / JEP 437
Launching Millions of Threads is no better
than GOTO
Nathaniel Smith
Structured Concurrency (JEP 428)
Goals
■ Improve the maintainability,
reliability, and observability of
multithreaded code.
■ Promote a style of concurrent
programming which can
eliminate common risks arising
from cancellation and shutdown,
such as thread leaks and
cancellation delays.
Non-Goals
■ It is not a goal to replace any of the concurrency
constructs in the java.util.concurrent package,
such as ExecutorService and Future.
■ It is not a goal to define the definitive structured
concurrency API for Java. Other structured
concurrency constructs can be defined by
third-party libraries or in future JDK releases.
■ It is not a goal to define a means of sharing
streams of data among threads (i.e., channels). We
might propose to do so in the future.
■ It is not a goal to replace the existing thread
interruption mechanism with a new thread
cancellation mechanism. We might propose to do so
in the future.
Structured Concurrency (JEP 428)
● with so many threads running you need management and control
structures
● since JDK 5 no direct interaction with Threads but submit to
ExecutorService -> Future
● ExecutorService is still unstructured
● Multi-Thread Control structures are missing in Java (like Erlang/Akka)
○ even if they exist in the business process
○ no task->subtask relationships between threads
○ every thread can read from a future or submit to an executor
● Loom keeps this model -> Structure is missing
● what happens when a (child or parent) thread fails?
Comparison
Response handle()
throws ExecutionException, InterruptedException{
Future<String> user =
ex.submit(() -> findUser());
Future<Integer> order =
ex.submit(() -> fetchOrder());
// Join findUser
String theUser = user.get();
// Join fetchOrder
int theOrder = order.get();
return new Response(theUser, theOrder);
}
StructuredTaskScope Example
try ( var scope = new StructuredTaskScope<String>() ) {
var future1 = scope.fork(task1);
var future2 = scope.fork(task2);
scope.join();
return switch (future1.state()) {
case Future.SUCCESS -> future1.resultNow();
case Future.FAILED -> future1.exceptionNow();
}
} API StructuredTaskScope
StructuredTaskScope.ShutdownOnSuccess
import jdk.incubator.concurrent.*;
try ( var scope = new StructuredTaskScope.ShutdownOnSuccess<String>() ) {
IntStream.range(0,10).forEach(i ->
scope.fork(() -> String.valueOf(i)));
scope.join();
// first returning wins, exception if none did
System.out.println(scope.result());
}
● ShutdownOnFailure - same just for fail-fast API StructuredTaskScope
● more explicit clarity of what happens
● specialized, auto-closeable, short-lived execution-scope
● like an executor, but uses virtual Threads and FJP
● submit tasks to it (fork()) all work on behalf of scope
● StructuredTaskScope<T>()
● Future<T> future = scope.fork(task);
● scope.join() -> returns when all tasks are complete
● switch on future.state() (FAILED, RUNNING, SUCCESS, CANCELLED)
○ future.resultNow() / future.exceptionNow()
● better with specialized implementations (first-one-wins or fail-fast)
○ if one fails, others are cancelled via ShutdownOnFailure cancellation policy
● auto-cleanup
Scope - virtual thread launcher
● to implement your own "structured business logic"
● Subclass StructuredTaskScope
● override handleComplete(Future<T>)
● depending on future-state, do what you need to do
● is called concurrently, needs to use thread safe instance state
● custom result method, reduce state to a result (or Exception)
● Concern: Still a lot of multi-threaded technical infrastructure complexity
Your own Scope
JEP Café #13
Scoped Values!
since Java 20
JEP 429
(was ExtendedLocal)
Thread Locals - we all know and love
● since Java 1.2
● Thread local/safe access (guaranteed)
● Store mutable state on a thread
○ Side-channel communication
● Can leak memory, until garbage collected or remove() called
● Inherited by child threads
● Smaller issue with platform threads
● Work with Virtual Threads, but
● Massive issue with huge amount of virtual threads
Scoped Values for the Rescue (JEP 429 - Incubated)
Immutable one-way communication of data to called runnables
● Define value - types
● Set up scope(s) with initializer per variable with .where(VAR, value)
● Bindings only valid during run(lambda) scope
private static final ScopedValue<..> VAL = ScopedValue.newInstance();
// Set up scope, each where yields a new scope
ScopedValue.where(VAL, <value>).where(VAL2, <value2>)
// use scope
.run(() -> { ... VAL.get() ... call methods ... });
Scoped Values for the Rescue
API Documentation
Example
import jdk.incubator.concurrent.*;
private static final ScopedValue<String> VERSION =
ScopedValue.newInstance();
Runnable runnable = () -> System.out.println(VERSION.get());
ScopedValue.where(VERSION, "Java 19", () ->
System.out.println(VERSION.get()));
var s = ScopedValue.where(VERSION, "Java 20");
s.run(runnable); // Java 20
s.where(VERSION, "Java 21").run(runnable); // Java 21
s.run(runnable); // Java 20
● Stacktrace in IDE-Debuggers (as expected)
● Patches in Java Debug Wire Protocol (JWDP) & Java Debugger Interface (JDI)
● Challenge - Display Millions of Threads
● Structured concurrency can help here too (Tree-Display)
● JFR should work - match allocations, method calls, etc. to virtual Threads
● Gaps in Thread API:
○ list all running threads
○ carrier <-> virtual thread
Loom Debugging - Just regular!?
wiki.openjdk.org/display/loom/Debugger+Support
Loom Demos &
Comparisions
github.com/ebarlas
Web-Backend
Game of Life
5M persistent connections
Elliot Barlas - MicroHttp - LogMeIn
Performance Comparison
Web-Server calling Backend
github.com/ebarlas/project-loom-comparison
WebServer
● Browser (ab)
● Web-Server calling
● 3x Backend (0,3s latency)
○ Authentication
○ Authorization
○ Database
● 3 implementations
○ Platform Threads
○ Asynchronous
○ Virtual Threads
public void handle(Request request, Consumer<Response> callback) {
executorService.execute(() -> callback.accept(doHandle(request)));
}
Response doHandle(Request request) {
var token = request.header("Authorization");
var authentication = sendRequestFor("/authenticate?token=" + token, …);
var authorization = sendRequestFor("/authorize?id=" + authentication.userId(), ..);
var meetings = sendRequestFor("/meetings?id=" + authentication.userId(), …);
var headers = List.of(new Header("Content-Type", "application/json"));
return new Response(200, "OK", headers, Json.toJson(meetings));
}
<T> T sendRequestFor(String endpoint, Class<T> type)
throws IOException, InterruptedException {
URI uri = URI.create("http://%s%s".formatted(backend, endpoint));
var request = HttpRequest.newBuilder().uri(uri).GET().build();
HttpResponse<String> response = httpClient.send(request,
HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("error occurred contacting "+endpoint);
}
return Json.fromJson(response.body(), type);
}
Same old Executor (for both Platform & Virtual Threads)
Helidon Nima
java --enable-preview -jar nima/target/example-nima-blocking.jar
2022.09.22 02:36:05.204 Logging at initialization configured using classpath: /logging.properties
2022.09.22 02:36:05.394 [0x6e82e640] http://127.0.0.1:8080 bound for socket '@default'
2022.09.22 02:36:05.396 [0x6e82e640] async writes, queue length: 32
2022.09.22 02:36:05.403 Níma server started all channels in 8 milliseconds. 244 milliseconds since JVM startup. Java
19+36-2238
ab -n 10000 -c 8 http://127.0.0.1:8080/one
Concurrency Level: 8
Time taken for tests: 0.848 seconds
Complete requests: 10000
Requests per second: 11797.14 [#/sec] (mean)
Time per request: 0.678 [ms] (mean)
Time per request: 0.085 [ms] (mean, across all concurrent requests)
Transfer rate: 0.00 [Kbytes/sec] received
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 0.0 0 0
Processing: 0 0 0.0 0 0
Waiting: 0 0 0.0 0 0
Total: 0 0 0.0 0 1
Nima Test
Helidon Nima
Note: In either case, you should not
“obstruct” the thread. Obstruction is a
long-term, full utilization of the thread.
In a reactive framework this would
consume one of the event loop threads
effectively stopping the server. In
blocking (Níma) this may cause an
issue with the “pinned thread”. In both
cases this can be resolved by
off-loading the heavy load to a
dedicated executor service using
platform threads.
Performance comparable to Netty pipelined
Note: What we can see from these numbers
(and what is our goal with Níma) is that we
can achieve performance comparable to a
minimalist Netty server, while maintaining
a simple, easy to use programming model.
Game of Life
CSP - Communicating Sequential Processes
github.com/ebarlas/game-of-life-csp
CSP - Not possible in Java before
● Channel (BlockingQueue<Boolean>) to exchange information
● Grid - Channel<boolean[][]>
● Each Cell has
○ a virtual thread
○ channels for ticks and results (width x height x 2)
○ one channel per neighbour (~ width x height x 8)
○ aka a LOT of channels/queues
Wikipedia CSP
Cell's biological Clock - "Life"
private void run() {
while (true) {
tickChannel.take(); // wait for tick stimulus
// announce liveness to neighbors
outChannels.forEach(ch -> ch.put(alive));
// receive liveness from neighbors
int neighbors = inChannels.stream()
.map(Channel::take)
.mapToInt(b -> b ? 1 : 0).sum();
// calculate next state based on game of life rules
alive = alive && neighbors == 2 || neighbors == 3;
// announce resulting next state
resultChannel.put(alive);
}
}
● take / put -> block -> suspend
● exchange via channel/queue
● write only to local state
Mario Fusco 🚀
Improved channel datastructures
yield massive improvements
speakerdeck.com/mariofusco
Speaking Tour
Resources
(there is a lot)
● JEP 425 - Virtual Threads (Java 19)
● JEP 436 - Virtual Threads (Java 20)
● JEP 428 - Structured Concurrency
● JEP Café #12 - 10M Threads
● JEP Café #13 - Loom Tutorial
● Heinz Kabutz Loom Video
● JavaSpektrum Loom (me)
● Loom Lab (Nicolai Parlog)
● Million Virtual Threads
● Virtual Threads PR
● Loom Talk Pressler Bates Devoxx
● Loom Deep Dive: Paumard Forax Devoxx
● Loom Wiki
● Inside Java Loom
● Loom Networking under the Hood
● InfoQ Interview Ron Pressler
● State Of Loom Part 1 (Part 2)
● Helidon Nima
● Loom and Thread Fairness (Morling)
● Loom Comparison
● Structured Concurrency
● Mario Fusco: Game of Loom
Resources
A celebratory poem
In threads of fate, a loom converged,
A tapestry of change emerged,
From distant shores, the world was swirled,
As one, concurrent threads unfurled.
-- courtesy GPT-4
What can you do?
Test! Provide feedback!
Don't use in production (yet)!
Thank You!
… I'd love to take questions!

More Related Content

What's hot

Mocking in Java with Mockito
Mocking in Java with MockitoMocking in Java with Mockito
Mocking in Java with MockitoRichard Paul
 
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and MockitoAn Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockitoshaunthomas999
 
[教材] 例外處理設計與重構實作班201309
[教材] 例外處理設計與重構實作班201309[教材] 例外處理設計與重構實作班201309
[教材] 例外處理設計與重構實作班201309teddysoft
 
C/C++とWebAssemblyを利用したライブラリ開発
C/C++とWebAssemblyを利用したライブラリ開発C/C++とWebAssemblyを利用したライブラリ開発
C/C++とWebAssemblyを利用したライブラリ開発祐司 伊藤
 
OWASP AppSecCali 2015 - Marshalling Pickles
OWASP AppSecCali 2015 - Marshalling PicklesOWASP AppSecCali 2015 - Marshalling Pickles
OWASP AppSecCali 2015 - Marshalling PicklesChristopher Frohoff
 
3.Java EE7 徹底入門 CDI&EJB
3.Java EE7 徹底入門 CDI&EJB3.Java EE7 徹底入門 CDI&EJB
3.Java EE7 徹底入門 CDI&EJBTsunenaga Hanyuda
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexprGenya Murakami
 
Testing with JUnit 5 and Spring
Testing with JUnit 5 and SpringTesting with JUnit 5 and Spring
Testing with JUnit 5 and SpringVMware Tanzu
 
「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」
「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」
「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」直久 住川
 
Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Yoshifumi Kawai
 
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層智啓 出川
 
Tester unitairement une application java
Tester unitairement une application javaTester unitairement une application java
Tester unitairement une application javaAntoine Rey
 
Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023
Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023
Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023Sam Brannen
 
HAProxy scale out using open source
HAProxy scale out using open sourceHAProxy scale out using open source
HAProxy scale out using open sourceIngo Walz
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案yohhoy
 
Pentesting GraphQL Applications
Pentesting GraphQL ApplicationsPentesting GraphQL Applications
Pentesting GraphQL ApplicationsNeelu Tripathy
 
CMake - Introduction and best practices
CMake - Introduction and best practicesCMake - Introduction and best practices
CMake - Introduction and best practicesDaniel Pfeifer
 
PowerShellが苦手だった男がPowerShellを愛するようになるまで
PowerShellが苦手だった男がPowerShellを愛するようになるまでPowerShellが苦手だった男がPowerShellを愛するようになるまで
PowerShellが苦手だった男がPowerShellを愛するようになるまでKazuhiro Matsushima
 
Test de logiciels
Test de logiciels Test de logiciels
Test de logiciels Bilel Abed
 

What's hot (20)

Mocking in Java with Mockito
Mocking in Java with MockitoMocking in Java with Mockito
Mocking in Java with Mockito
 
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and MockitoAn Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
 
[教材] 例外處理設計與重構實作班201309
[教材] 例外處理設計與重構實作班201309[教材] 例外處理設計與重構實作班201309
[教材] 例外處理設計與重構實作班201309
 
C/C++とWebAssemblyを利用したライブラリ開発
C/C++とWebAssemblyを利用したライブラリ開発C/C++とWebAssemblyを利用したライブラリ開発
C/C++とWebAssemblyを利用したライブラリ開発
 
OWASP AppSecCali 2015 - Marshalling Pickles
OWASP AppSecCali 2015 - Marshalling PicklesOWASP AppSecCali 2015 - Marshalling Pickles
OWASP AppSecCali 2015 - Marshalling Pickles
 
3.Java EE7 徹底入門 CDI&EJB
3.Java EE7 徹底入門 CDI&EJB3.Java EE7 徹底入門 CDI&EJB
3.Java EE7 徹底入門 CDI&EJB
 
中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr中3女子が狂える本当に気持ちのいい constexpr
中3女子が狂える本当に気持ちのいい constexpr
 
Testing with JUnit 5 and Spring
Testing with JUnit 5 and SpringTesting with JUnit 5 and Spring
Testing with JUnit 5 and Spring
 
「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」
「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」
「FPGA 開発入門:FPGA を用いたエッジ AI の高速化手法を学ぶ」
 
Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)Deep Dive async/await in Unity with UniTask(EN)
Deep Dive async/await in Unity with UniTask(EN)
 
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
2015年度GPGPU実践プログラミング 第5回 GPUのメモリ階層
 
Tester unitairement une application java
Tester unitairement une application javaTester unitairement une application java
Tester unitairement une application java
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023
Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023
Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023
 
HAProxy scale out using open source
HAProxy scale out using open sourceHAProxy scale out using open source
HAProxy scale out using open source
 
新しい並列for構文のご提案
新しい並列for構文のご提案新しい並列for構文のご提案
新しい並列for構文のご提案
 
Pentesting GraphQL Applications
Pentesting GraphQL ApplicationsPentesting GraphQL Applications
Pentesting GraphQL Applications
 
CMake - Introduction and best practices
CMake - Introduction and best practicesCMake - Introduction and best practices
CMake - Introduction and best practices
 
PowerShellが苦手だった男がPowerShellを愛するようになるまで
PowerShellが苦手だった男がPowerShellを愛するようになるまでPowerShellが苦手だった男がPowerShellを愛するようになるまで
PowerShellが苦手だった男がPowerShellを愛するようになるまで
 
Test de logiciels
Test de logiciels Test de logiciels
Test de logiciels
 

Similar to Looming Marvelous - Virtual Threads in Java Javaland.pdf

Java Threads: Lightweight Processes
Java Threads: Lightweight ProcessesJava Threads: Lightweight Processes
Java Threads: Lightweight ProcessesIsuru Perera
 
Programming with Threads in Java
Programming with Threads in JavaProgramming with Threads in Java
Programming with Threads in Javakoji lin
 
Modern Java Concurrency
Modern Java ConcurrencyModern Java Concurrency
Modern Java ConcurrencyBen Evans
 
node.js 실무 - node js in practice by Jesang Yoon
node.js 실무 - node js in practice by Jesang Yoonnode.js 실무 - node js in practice by Jesang Yoon
node.js 실무 - node js in practice by Jesang YoonJesang Yoon
 
Java Future S Ritter
Java Future S RitterJava Future S Ritter
Java Future S Rittercatherinewall
 
Microservices with Micronaut
Microservices with MicronautMicroservices with Micronaut
Microservices with MicronautQAware GmbH
 
Microservices with Micronaut
Microservices with MicronautMicroservices with Micronaut
Microservices with MicronautQAware GmbH
 
Profiler Guided Java Performance Tuning
Profiler Guided Java Performance TuningProfiler Guided Java Performance Tuning
Profiler Guided Java Performance Tuningosa_ora
 
Here comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfHere comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfKrystian Zybała
 
Java Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
Java Core | Modern Java Concurrency | Martijn Verburg & Ben EvansJava Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
Java Core | Modern Java Concurrency | Martijn Verburg & Ben EvansJAX London
 
Modern Java Concurrency (OSCON 2012)
Modern Java Concurrency (OSCON 2012)Modern Java Concurrency (OSCON 2012)
Modern Java Concurrency (OSCON 2012)Martijn Verburg
 
Java troubleshooting thread dump
Java troubleshooting thread dumpJava troubleshooting thread dump
Java troubleshooting thread dumpejlp12
 
Concurrency - Why it's hard ?
Concurrency - Why it's hard ?Concurrency - Why it's hard ?
Concurrency - Why it's hard ?Ramith Jayasinghe
 
What’s expected in Java 9
What’s expected in Java 9What’s expected in Java 9
What’s expected in Java 9Gal Marder
 
Breaking The Clustering Limits @ AlphaCSP JavaEdge 2007
Breaking The Clustering Limits @ AlphaCSP JavaEdge 2007Breaking The Clustering Limits @ AlphaCSP JavaEdge 2007
Breaking The Clustering Limits @ AlphaCSP JavaEdge 2007Baruch Sadogursky
 
Concurrent Programming in Java
Concurrent Programming in JavaConcurrent Programming in Java
Concurrent Programming in JavaRuben Inoto Soto
 

Similar to Looming Marvelous - Virtual Threads in Java Javaland.pdf (20)

Java Threads: Lightweight Processes
Java Threads: Lightweight ProcessesJava Threads: Lightweight Processes
Java Threads: Lightweight Processes
 
Programming with Threads in Java
Programming with Threads in JavaProgramming with Threads in Java
Programming with Threads in Java
 
Modern Java Concurrency
Modern Java ConcurrencyModern Java Concurrency
Modern Java Concurrency
 
node.js 실무 - node js in practice by Jesang Yoon
node.js 실무 - node js in practice by Jesang Yoonnode.js 실무 - node js in practice by Jesang Yoon
node.js 실무 - node js in practice by Jesang Yoon
 
Java Future S Ritter
Java Future S RitterJava Future S Ritter
Java Future S Ritter
 
Microservices with Micronaut
Microservices with MicronautMicroservices with Micronaut
Microservices with Micronaut
 
JavaScript Event Loop
JavaScript Event LoopJavaScript Event Loop
JavaScript Event Loop
 
Microservices with Micronaut
Microservices with MicronautMicroservices with Micronaut
Microservices with Micronaut
 
Profiler Guided Java Performance Tuning
Profiler Guided Java Performance TuningProfiler Guided Java Performance Tuning
Profiler Guided Java Performance Tuning
 
Here comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfHere comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdf
 
Java Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
Java Core | Modern Java Concurrency | Martijn Verburg & Ben EvansJava Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
Java Core | Modern Java Concurrency | Martijn Verburg & Ben Evans
 
Modern Java Concurrency (OSCON 2012)
Modern Java Concurrency (OSCON 2012)Modern Java Concurrency (OSCON 2012)
Modern Java Concurrency (OSCON 2012)
 
ForkJoinPools and parallel streams
ForkJoinPools and parallel streamsForkJoinPools and parallel streams
ForkJoinPools and parallel streams
 
Java troubleshooting thread dump
Java troubleshooting thread dumpJava troubleshooting thread dump
Java troubleshooting thread dump
 
Concurrency - Why it's hard ?
Concurrency - Why it's hard ?Concurrency - Why it's hard ?
Concurrency - Why it's hard ?
 
What’s expected in Java 9
What’s expected in Java 9What’s expected in Java 9
What’s expected in Java 9
 
Java concurrency
Java concurrencyJava concurrency
Java concurrency
 
Breaking The Clustering Limits @ AlphaCSP JavaEdge 2007
Breaking The Clustering Limits @ AlphaCSP JavaEdge 2007Breaking The Clustering Limits @ AlphaCSP JavaEdge 2007
Breaking The Clustering Limits @ AlphaCSP JavaEdge 2007
 
Concurrent Programming in Java
Concurrent Programming in JavaConcurrent Programming in Java
Concurrent Programming in Java
 
Why Concurrency is hard ?
Why Concurrency is hard ?Why Concurrency is hard ?
Why Concurrency is hard ?
 

More from jexp

Easing the daily grind with the awesome JDK command line tools
Easing the daily grind with the awesome JDK command line toolsEasing the daily grind with the awesome JDK command line tools
Easing the daily grind with the awesome JDK command line toolsjexp
 
Looming Marvelous - Virtual Threads in Java
Looming Marvelous - Virtual Threads in JavaLooming Marvelous - Virtual Threads in Java
Looming Marvelous - Virtual Threads in Javajexp
 
GraphConnect 2022 - Top 10 Cypher Tuning Tips & Tricks.pptx
GraphConnect 2022 - Top 10 Cypher Tuning Tips & Tricks.pptxGraphConnect 2022 - Top 10 Cypher Tuning Tips & Tricks.pptx
GraphConnect 2022 - Top 10 Cypher Tuning Tips & Tricks.pptxjexp
 
Neo4j Connector Apache Spark FiNCENFiles
Neo4j Connector Apache Spark FiNCENFilesNeo4j Connector Apache Spark FiNCENFiles
Neo4j Connector Apache Spark FiNCENFilesjexp
 
How Graphs Help Investigative Journalists to Connect the Dots
How Graphs Help Investigative Journalists to Connect the DotsHow Graphs Help Investigative Journalists to Connect the Dots
How Graphs Help Investigative Journalists to Connect the Dotsjexp
 
The Home Office. Does it really work?
The Home Office. Does it really work?The Home Office. Does it really work?
The Home Office. Does it really work?jexp
 
Polyglot Applications with GraalVM
Polyglot Applications with GraalVMPolyglot Applications with GraalVM
Polyglot Applications with GraalVMjexp
 
Neo4j Graph Streaming Services with Apache Kafka
Neo4j Graph Streaming Services with Apache KafkaNeo4j Graph Streaming Services with Apache Kafka
Neo4j Graph Streaming Services with Apache Kafkajexp
 
How Graph Databases efficiently store, manage and query connected data at s...
How Graph Databases efficiently  store, manage and query  connected data at s...How Graph Databases efficiently  store, manage and query  connected data at s...
How Graph Databases efficiently store, manage and query connected data at s...jexp
 
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures LibraryAPOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Libraryjexp
 
Refactoring, 2nd Edition
Refactoring, 2nd EditionRefactoring, 2nd Edition
Refactoring, 2nd Editionjexp
 
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...jexp
 
GraphQL - The new "Lingua Franca" for API-Development
GraphQL - The new "Lingua Franca" for API-DevelopmentGraphQL - The new "Lingua Franca" for API-Development
GraphQL - The new "Lingua Franca" for API-Developmentjexp
 
A whirlwind tour of graph databases
A whirlwind tour of graph databasesA whirlwind tour of graph databases
A whirlwind tour of graph databasesjexp
 
Practical Graph Algorithms with Neo4j
Practical Graph Algorithms with Neo4jPractical Graph Algorithms with Neo4j
Practical Graph Algorithms with Neo4jjexp
 
A Game of Data and GraphQL
A Game of Data and GraphQLA Game of Data and GraphQL
A Game of Data and GraphQLjexp
 
Querying Graphs with GraphQL
Querying Graphs with GraphQLQuerying Graphs with GraphQL
Querying Graphs with GraphQLjexp
 
Graphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present FutureGraphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present Futurejexp
 
Intro to Graphs and Neo4j
Intro to Graphs and Neo4jIntro to Graphs and Neo4j
Intro to Graphs and Neo4jjexp
 
Class graph neo4j and software metrics
Class graph neo4j and software metricsClass graph neo4j and software metrics
Class graph neo4j and software metricsjexp
 

More from jexp (20)

Easing the daily grind with the awesome JDK command line tools
Easing the daily grind with the awesome JDK command line toolsEasing the daily grind with the awesome JDK command line tools
Easing the daily grind with the awesome JDK command line tools
 
Looming Marvelous - Virtual Threads in Java
Looming Marvelous - Virtual Threads in JavaLooming Marvelous - Virtual Threads in Java
Looming Marvelous - Virtual Threads in Java
 
GraphConnect 2022 - Top 10 Cypher Tuning Tips & Tricks.pptx
GraphConnect 2022 - Top 10 Cypher Tuning Tips & Tricks.pptxGraphConnect 2022 - Top 10 Cypher Tuning Tips & Tricks.pptx
GraphConnect 2022 - Top 10 Cypher Tuning Tips & Tricks.pptx
 
Neo4j Connector Apache Spark FiNCENFiles
Neo4j Connector Apache Spark FiNCENFilesNeo4j Connector Apache Spark FiNCENFiles
Neo4j Connector Apache Spark FiNCENFiles
 
How Graphs Help Investigative Journalists to Connect the Dots
How Graphs Help Investigative Journalists to Connect the DotsHow Graphs Help Investigative Journalists to Connect the Dots
How Graphs Help Investigative Journalists to Connect the Dots
 
The Home Office. Does it really work?
The Home Office. Does it really work?The Home Office. Does it really work?
The Home Office. Does it really work?
 
Polyglot Applications with GraalVM
Polyglot Applications with GraalVMPolyglot Applications with GraalVM
Polyglot Applications with GraalVM
 
Neo4j Graph Streaming Services with Apache Kafka
Neo4j Graph Streaming Services with Apache KafkaNeo4j Graph Streaming Services with Apache Kafka
Neo4j Graph Streaming Services with Apache Kafka
 
How Graph Databases efficiently store, manage and query connected data at s...
How Graph Databases efficiently  store, manage and query  connected data at s...How Graph Databases efficiently  store, manage and query  connected data at s...
How Graph Databases efficiently store, manage and query connected data at s...
 
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures LibraryAPOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
APOC Pearls - Whirlwind Tour Through the Neo4j APOC Procedures Library
 
Refactoring, 2nd Edition
Refactoring, 2nd EditionRefactoring, 2nd Edition
Refactoring, 2nd Edition
 
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
New Features in Neo4j 3.4 / 3.3 - Graph Algorithms, Spatial, Date-Time & Visu...
 
GraphQL - The new "Lingua Franca" for API-Development
GraphQL - The new "Lingua Franca" for API-DevelopmentGraphQL - The new "Lingua Franca" for API-Development
GraphQL - The new "Lingua Franca" for API-Development
 
A whirlwind tour of graph databases
A whirlwind tour of graph databasesA whirlwind tour of graph databases
A whirlwind tour of graph databases
 
Practical Graph Algorithms with Neo4j
Practical Graph Algorithms with Neo4jPractical Graph Algorithms with Neo4j
Practical Graph Algorithms with Neo4j
 
A Game of Data and GraphQL
A Game of Data and GraphQLA Game of Data and GraphQL
A Game of Data and GraphQL
 
Querying Graphs with GraphQL
Querying Graphs with GraphQLQuerying Graphs with GraphQL
Querying Graphs with GraphQL
 
Graphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present FutureGraphs & Neo4j - Past Present Future
Graphs & Neo4j - Past Present Future
 
Intro to Graphs and Neo4j
Intro to Graphs and Neo4jIntro to Graphs and Neo4j
Intro to Graphs and Neo4j
 
Class graph neo4j and software metrics
Class graph neo4j and software metricsClass graph neo4j and software metrics
Class graph neo4j and software metrics
 

Recently uploaded

Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfjimielynbastida
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationSlibray Presentation
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitecturePixlogix Infotech
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024BookNet Canada
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Neo4j
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):comworks
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Scott Keck-Warren
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksSoftradix Technologies
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsMemoori
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...Fwdays
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machinePadma Pradeep
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfngoud9212
 

Recently uploaded (20)

Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Panjabi Bagh 🔝 9953056974 🔝 Delhi escort Service
 
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptxVulnerability_Management_GRC_by Sohang Sengupta.pptx
Vulnerability_Management_GRC_by Sohang Sengupta.pptx
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Pigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping ElbowsPigging Solutions Piggable Sweeping Elbows
Pigging Solutions Piggable Sweeping Elbows
 
Science&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdfScience&tech:THE INFORMATION AGE STS.pdf
Science&tech:THE INFORMATION AGE STS.pdf
 
Connect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck PresentationConnect Wave/ connectwave Pitch Deck Presentation
Connect Wave/ connectwave Pitch Deck Presentation
 
Understanding the Laravel MVC Architecture
Understanding the Laravel MVC ArchitectureUnderstanding the Laravel MVC Architecture
Understanding the Laravel MVC Architecture
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
New from BookNet Canada for 2024: BNC BiblioShare - Tech Forum 2024
 
Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024Build your next Gen AI Breakthrough - April 2024
Build your next Gen AI Breakthrough - April 2024
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):CloudStudio User manual (basic edition):
CloudStudio User manual (basic edition):
 
Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024Advanced Test Driven-Development @ php[tek] 2024
Advanced Test Driven-Development @ php[tek] 2024
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
Benefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other FrameworksBenefits Of Flutter Compared To Other Frameworks
Benefits Of Flutter Compared To Other Frameworks
 
AI as an Interface for Commercial Buildings
AI as an Interface for Commercial BuildingsAI as an Interface for Commercial Buildings
AI as an Interface for Commercial Buildings
 
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks..."LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
"LLMs for Python Engineers: Advanced Data Analysis and Semantic Kernel",Oleks...
 
Install Stable Diffusion in windows machine
Install Stable Diffusion in windows machineInstall Stable Diffusion in windows machine
Install Stable Diffusion in windows machine
 
Bluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdfBluetooth Controlled Car with Arduino.pdf
Bluetooth Controlled Car with Arduino.pdf
 

Looming Marvelous - Virtual Threads in Java Javaland.pdf

  • 1. Project Loom - Einfachere Nebenläufigkeit in Java Ein Thread, ist ein Thread, ist ein (virtueller) Thread. Code Examples
  • 2. Leading developer relations & community at the totally best graph database Who's talking? Michael Hunger Learning new things every day Having fun with code, open-source, people Java Working with Java since 1995 Jug-Saxony JavaChampion Neo4j TechnoGirls Supporting girls to learn to code
  • 3. Welcome Java 20 Mar 21, 2023 sdk install java 20-open openjdk 20 2023-03-21 build 20+36-2344
  • 4. Why are we talking about this ? Concurrency ? Parallelism?
  • 5. There is a lot to do in a Java Program Image Credit Marcus Biel / cleancodeacademy
  • 6. ● Process and answer requests ● Compute ● I/O: Read and write files ● Read from databases and network ● Synchronization ● Render ● Logging / Monitoring / Metrics ● Garbage collection There is a lot to do! And limited resources ● Developer Brain ● CPU / Hyperthreading ● Memory ● I / O ● Network ● Disk
  • 8. Been There - Seen That Java 1.1 - 1997 Green Threads Java 1.3 - 1998 Native Threads Java 1.5 - 2004 Thread Pools / Executors Java 8 2014-2016 CompletableFuture Rx-Java Reactive Streams Reactor 2017-2018 Java 9 Flow Kotlin Coroutines - Stable Java 19, 2022 JEP 425 Virtual Threads Preview Java 1.7 2011 ForkJoinPool Parallel Streams Java 20, 2023 JEP 436 Virtual Threads 2nd Preview
  • 10. A Thread ● Asynchronous Unit of Execution ● Multiple Threads running inside a Process ● One Thread at a time on a CPU ● Inside a thread - synchronous execution ● Switching - Switch/Save Registers / Invalidate Caches … ● Cheaper than process switching, HW support ● green (<1.3), platform/native, now virtual Threads
  • 11. Green Threads vs. Native Threads Green Threads ● User Level Threads ● Simulated Multithreading ● Runs on single (LW)Process / CPU ● Scheduled by VM, not OS ● Lots of HW context switching ● "slow" ● Abandoned in Java 1.3 ● Management / State overhead Native Threads ● Mapped to all HW Threads (HT) ● Limited to HW concurrency ● blocking, synchronous execution ● Since Java 1.3 (Solaris - 1.2) ● Better on I/O & context-switching ● Faster than process based concurrency And now we have virtual Threads…
  • 12. Java Concurrency looks easier than it is Devil is in the details (Brian Goetz - JCP book)
  • 14. Hello Threading World Example Code & Run 1. new Thread().start() 2. ThreadPool/Executor 3. Reactive Streams/Reactor/Akka 4. Kotlin Coroutines 5. Loom - Virtual Threads
  • 15. Java Threads & Thread Pools var t = new Thread(() -> System.out.println("Hello World")); t.start(); t.join(); // new! Thread.Builder var t = Thread.ofPlatform().start( () -> System.out.println("Hello new World")); t.join();
  • 16. Thread Pools try (var executor = Executors.newFixedThreadPool(5)) { IntStream.range(0, 50).forEach(i -> { executor.submit(() -> System.out.println("Hello Platform Thread "+i+" "+Thread.currentThread()) ); }); } // executor.close()
  • 17. Thread Pools // takes a long time try (var executor = Executors.newFixedThreadPool(10)) { IntStream.range(0, 10_000).forEach(i -> { executor.submit(() -> { Thread.sleep(Duration.ofSeconds(1)); return i; }); }); } // executor.close()
  • 18. // parallel stream IntStream.range(1,10).parallel() .mapToObj( i -> "Hello World "+i) .forEach(System.out::println); Parallel Streams
  • 19. // Completable Future var cf = CompletableFuture.completedFuture("complex") .thenApplyAsync(String::toUpperCase) .thenCombine( CompletableFuture.completedFuture("CODE") .thenApplyAsync(String::toLowerCase), (s1, s2) -> s1 + s2); cf.join() Completable Future
  • 20. Reactive Programming Reactive Java, Reactor, RxJava, Akka String key = "message"; Mono<String> r = Mono.just("Hello") .flatMap(s -> Mono.deferContextual(ctx -> Mono.just(s + " " + ctx.get(key)))) .contextWrite(ctx -> ctx.put(key, "World")); StepVerifier.create(r).expectNext("Hello World").verifyComplete(); Reactor Documentation
  • 21. Kotlin Coroutines Documentation fun main() = runBlocking { // this: CoroutineScope launch { doWorld() } println("Hello") } // suspending function suspend fun doWorld() { delay(1000L) println("World!") }
  • 23. Blocking vs. Non-Blocking vs. Continuations Blocking ● linear program-flow ● execute what you wrote, easy to reason ● blocks on intensive operations ● inefficient use of resources (utilized/blocked) ● classical Java Threading Continuation ● ability to capture computation so far and continue later ● explicit continuations (await, async, yield) ● implicit continuations (on entry-points to blocking ops) ● simpler API ● hard work is in the implementation ● Kotlin, JS, Loom Non-Blocking ● DSL for describing a processing ● underlying reactive engine ● data flow ● resource efficient ● hard to reason, debug unit-test, profile, maintain ● large complex API ● difficult to correlate operations ● RxJava, Reactive Streams, Akka
  • 24. Concurrency & Parallelism help us make more efficient use of existing resources
  • 26. Concurrency vs. Parallelism Concurrency ● Ability to execute many (different) tasks and make progress on all of them ● Seemingly simultaneously (e.g. on 1 CPU) Parallel Concurrent Execution ● Multiple tasks are executed concurrently (at the same time) AND ● Multiple CPUs are used to execute tasks in parallel ● Most common today Parallel Execution ● Utilize more than 1 CPU/Thread to progress multiple tasks simultaneously Parallelism ● Ability to divide and conquer a single task into subtasks that can be executed in parallel source: jenkov.com
  • 27. Concurrent Parallel Execution Parallel Concurrent Execution CPU Task 1 Task 2 CPU Task 1 Task 2 CPU CPU Task 1 Task 2 CPU Task 3 Task 4 Parallelism CPU Thread 1 Thread 2 CPU Thread 3 Thread 4
  • 28. Parallel Execution Challenges ● Context Switches / Caches / Branch Predictions ● Race Conditions ● Mutable data / visibility ● Deadlocks ● Starvation ● Resource over- / underutilization ● Immutability / Ownership ● Reasoning / Debugging / Logging ● State-Management ● Execution Depedencies
  • 29. Project Loom JEP 425 / JEP 436 Image OpenJDK / Sharat Chander
  • 30. JEP Process JEP 425 1st Preview Java 19 Sept 2022 Delivered JEP 436 2nd Preview Java 20 Mar 2023 Delivered JEP Draft Finalization Java 21 Sept 2023 Submitted ● Thread Locals Support ● Virtual Thread API ● Thread.Builder ● VirtualThreadPoolExecutor ● Continuations impl ● StructuredConcurrency (inc.) ● StructuredConcurrency ● Scoped Variables
  • 31. JEP 425/436 - Project Loom - openjdk.org/jeps/425 …/436
  • 32. Goals ● Enable server applications written in the simple thread-per-request style to scale with near-optimal hardware utilization. ● Enable existing code that uses the java.lang.Thread API to adopt virtual threads with minimal change. ● Enable easy troubleshooting, debugging, and profiling of virtual threads with existing JDK tools. Loom - Goals Non-Goals ● It is not a goal to remove the traditional implementation of threads, or to silently migrate existing applications to use virtual threads. ● It is not a goal to change the basic concurrency model of Java. ● It is not a goal to offer a new data parallelism construct in either the Java language or the Java libraries. The Stream API remains the preferred way to process large data sets in parallel.
  • 34. ● Continuations internally in the JVM ● Reimplementation of Networking / IO Code in JVM ● lightweight Virtual Thread, same API as java.util.Thread ● Thread.Builder ● VirtualThreadExecutors ● Auto-Closeable Excecutors ● Structured Concurrency (StructuredTaskScope) Java 20 ● Scoped Values + their support in StructuredTaskScope ● StructuredTaskScope still incubator What's in the boxcup?
  • 36. Virtual Thread ● same, stable API as traditional thread (deprecations will be removed) ● handled differently during blocking operations ● lightweight (300 bytes) like a Runnable, JVM can execute millions ● temporarily bound to a platform (carrier) thread ● on each blocking/parking operation -> Continuation yielding ● stack is copied to heap ● on resume, stack copied back and ● execution resumed on different carrier Thread ● uses a separate ForkJoinPool (FJP), to also prevent starving -Djdk.defaultScheduler.parallelism=N
  • 37. var threads = IntStream.range(0,10).mapToObj(i -> Thread.ofVirtual().start(() -> { // or Thread.startVirtualThread(runnable) System.out.println("Hello Virtual Thread "+i+" "+Thread.currentThread()); })).toList(); for (Thread t : threads) { t.join(); } Java Virtual Threads - Builder Hello Virtual Thread 3 VirtualThread[#10079]/runnable@ForkJoinPool-1-worker-18 Hello Virtual Thread 6 VirtualThread[#10082]/runnable@ForkJoinPool-1-worker-17 Hello Virtual Thread 1 VirtualThread[#10077]/runnable@ForkJoinPool-1-worker-16 Hello Virtual Thread 5 VirtualThread[#10081]/runnable@ForkJoinPool-1-worker-15 Hello Virtual Thread 7 VirtualThread[#10083]/runnable@ForkJoinPool-1-worker-17 Hello Virtual Thread 2 VirtualThread[#10078]/runnable@ForkJoinPool-1-worker-17 Hello Virtual Thread 4 VirtualThread[#10080]/runnable@ForkJoinPool-1-worker-17 Hello Virtual Thread 8 VirtualThread[#10084]/runnable@ForkJoinPool-1-worker-19 Hello Virtual Thread 9 VirtualThread[#10085]/runnable@ForkJoinPool-1-worker-18
  • 38. Java Virtual Threads - Executor try (var executor = Executors.newVirtualThreadPerTaskExecutor()) { IntStream.range(0, 100_000).forEach(i -> { executor.submit(() -> { Thread.sleep(java.time.Duration.ofSeconds(1)); return i; // callable, throws Exception }); }); } // executor.close() is called implicitly, and waits
  • 40. New Rule: If in doubt Start a new virtual Thread
  • 42. // java --enable-preview --source 20 LoomServer.java // echo -n 'Hello Loom' | nc -n 127.0.0.1 2000 import java.io.*; import java.net.*; import java.util.concurrent.*; public class LoomServer { public static void main(String...args) throws IOException { try (var ss = new ServerSocket(2000); var pool = Executors.newVirtualThreadPerTaskExecutor()) { while (true) { var socket = ss.accept(); pool.execute(() -> { try (var s = socket; var in = s.getInputStream(); var out = s.getOutputStream()) { byte b = -1; while ((b = (byte)in.read()) != -1) { out.write(b+1); } } catch(IOException ioe) {} });
  • 43. Under The Hood ● Virtual Threads run on (different) Platform Threads ● They use a separate Fork Join Pool ● Instead of blocking (IO, networking, sleep, synchronization) they are yielding control ● Blocking Code in the JVM refactored to use Continuations ● Continuations move stack from Platform Thread to Heap ● Can pick up later on another thread ● Except when using addresses or native code
  • 44. Example Thread.sleep() ● Thread.sleep() ○ VThread.sleepNanos() ■ VThread.doSleepNanos() ● VTread.parkNanos() ○ VThread.yieldContinuation() ■ unmount() ■ Continuation.yield() static final ContinuationScope VTHREAD_SCOPE = new ContinuationScope("VirtualThreads"); @ChangesCurrentThread private boolean yieldContinuation() { boolean notifyJvmti = notifyJvmtiEvents; // unmount if (notifyJvmti) notifyJvmtiUnmountBegin(false); unmount(); try { return Continuation.yield(VTHREAD_SCOPE); } finally { // re-mount mount(); if (notifyJvmti) notifyJvmtiMountEnd(false); } } private void unmount() { // set Thread.currentThread() to return the platform thread Thread carrier = this.carrierThread; carrier.setCurrentThread(carrier); // break connection to carrier thread, synchronized with interrupt synchronized (interruptLock) { setCarrierThread(null); } carrier.clearInterrupt(); }
  • 45. Caveats or when does it not work? ● when stack cannot be moved to heap ● if it contains memory addresses (synchronized) -> use ReentrantLock! ● calls c-code ● File I/O ● DNS (Windows) ● then the task stays pinned to a platform thread ● to avoic exhaustion the FJP creates new temporary platform threads ● can track with -Djdk.tracePinnedThreads=full example by A. Sundararajan
  • 46. ● Large pull request (#8166) touching 1333 files ● Thread.Builder, virtualThreadPerTaskExecutor ● refactor all blocking/parking code to use Continuations for Virtual Threads ○ Network I/O, ○ Locks ○ Thread.sleep ● replace c-code where possible with Java code (e.g. in Method -> MethodHandles) ● not (yet): ○ File I/O (waiting for io_uring) ○ synchronized, due to address usage JDK Changes
  • 47. Continuations on the long way to Loom
  • 49. "A continuation is a callback function k that represents the current state of the program's execution. More precisely, the continuation k is a function of one argument, namely the value that has been computed so far, that returns the final value of the computation after the rest of the program has run to completion." A continuation
  • 51. import jdk.internal.vm.Continuation; import jdk.internal.vm.ContinuationScope; var scope = new ContinuationScope("scope"); var c = new Continuation(scope, () -> { System.out.println("Started"); Continuation.yield(scope); System.out.println("Running"); Continuation.yield(scope); System.out.println("Still running"); }); System.out.println("Start"); int i=0; while (!c.isDone()) { c.run(); System.out.println("Running "+i+" result "+c.isDone()); i++; } System.out.println("End"); Continuations in the JDK Start Started Running 0 result false Running Running 1 result false Still running Running 2 result true End
  • 53. Launching Millions of Threads is no better than GOTO Nathaniel Smith
  • 54. Structured Concurrency (JEP 428) Goals ■ Improve the maintainability, reliability, and observability of multithreaded code. ■ Promote a style of concurrent programming which can eliminate common risks arising from cancellation and shutdown, such as thread leaks and cancellation delays. Non-Goals ■ It is not a goal to replace any of the concurrency constructs in the java.util.concurrent package, such as ExecutorService and Future. ■ It is not a goal to define the definitive structured concurrency API for Java. Other structured concurrency constructs can be defined by third-party libraries or in future JDK releases. ■ It is not a goal to define a means of sharing streams of data among threads (i.e., channels). We might propose to do so in the future. ■ It is not a goal to replace the existing thread interruption mechanism with a new thread cancellation mechanism. We might propose to do so in the future.
  • 55. Structured Concurrency (JEP 428) ● with so many threads running you need management and control structures ● since JDK 5 no direct interaction with Threads but submit to ExecutorService -> Future ● ExecutorService is still unstructured ● Multi-Thread Control structures are missing in Java (like Erlang/Akka) ○ even if they exist in the business process ○ no task->subtask relationships between threads ○ every thread can read from a future or submit to an executor ● Loom keeps this model -> Structure is missing ● what happens when a (child or parent) thread fails?
  • 56. Comparison Response handle() throws ExecutionException, InterruptedException{ Future<String> user = ex.submit(() -> findUser()); Future<Integer> order = ex.submit(() -> fetchOrder()); // Join findUser String theUser = user.get(); // Join fetchOrder int theOrder = order.get(); return new Response(theUser, theOrder); }
  • 57. StructuredTaskScope Example try ( var scope = new StructuredTaskScope<String>() ) { var future1 = scope.fork(task1); var future2 = scope.fork(task2); scope.join(); return switch (future1.state()) { case Future.SUCCESS -> future1.resultNow(); case Future.FAILED -> future1.exceptionNow(); } } API StructuredTaskScope
  • 58. StructuredTaskScope.ShutdownOnSuccess import jdk.incubator.concurrent.*; try ( var scope = new StructuredTaskScope.ShutdownOnSuccess<String>() ) { IntStream.range(0,10).forEach(i -> scope.fork(() -> String.valueOf(i))); scope.join(); // first returning wins, exception if none did System.out.println(scope.result()); } ● ShutdownOnFailure - same just for fail-fast API StructuredTaskScope
  • 59. ● more explicit clarity of what happens ● specialized, auto-closeable, short-lived execution-scope ● like an executor, but uses virtual Threads and FJP ● submit tasks to it (fork()) all work on behalf of scope ● StructuredTaskScope<T>() ● Future<T> future = scope.fork(task); ● scope.join() -> returns when all tasks are complete ● switch on future.state() (FAILED, RUNNING, SUCCESS, CANCELLED) ○ future.resultNow() / future.exceptionNow() ● better with specialized implementations (first-one-wins or fail-fast) ○ if one fails, others are cancelled via ShutdownOnFailure cancellation policy ● auto-cleanup Scope - virtual thread launcher
  • 60. ● to implement your own "structured business logic" ● Subclass StructuredTaskScope ● override handleComplete(Future<T>) ● depending on future-state, do what you need to do ● is called concurrently, needs to use thread safe instance state ● custom result method, reduce state to a result (or Exception) ● Concern: Still a lot of multi-threaded technical infrastructure complexity Your own Scope JEP Café #13
  • 61. Scoped Values! since Java 20 JEP 429 (was ExtendedLocal)
  • 62. Thread Locals - we all know and love ● since Java 1.2 ● Thread local/safe access (guaranteed) ● Store mutable state on a thread ○ Side-channel communication ● Can leak memory, until garbage collected or remove() called ● Inherited by child threads ● Smaller issue with platform threads ● Work with Virtual Threads, but ● Massive issue with huge amount of virtual threads
  • 63. Scoped Values for the Rescue (JEP 429 - Incubated)
  • 64. Immutable one-way communication of data to called runnables ● Define value - types ● Set up scope(s) with initializer per variable with .where(VAR, value) ● Bindings only valid during run(lambda) scope private static final ScopedValue<..> VAL = ScopedValue.newInstance(); // Set up scope, each where yields a new scope ScopedValue.where(VAL, <value>).where(VAL2, <value2>) // use scope .run(() -> { ... VAL.get() ... call methods ... }); Scoped Values for the Rescue API Documentation
  • 65. Example import jdk.incubator.concurrent.*; private static final ScopedValue<String> VERSION = ScopedValue.newInstance(); Runnable runnable = () -> System.out.println(VERSION.get()); ScopedValue.where(VERSION, "Java 19", () -> System.out.println(VERSION.get())); var s = ScopedValue.where(VERSION, "Java 20"); s.run(runnable); // Java 20 s.where(VERSION, "Java 21").run(runnable); // Java 21 s.run(runnable); // Java 20
  • 66. ● Stacktrace in IDE-Debuggers (as expected) ● Patches in Java Debug Wire Protocol (JWDP) & Java Debugger Interface (JDI) ● Challenge - Display Millions of Threads ● Structured concurrency can help here too (Tree-Display) ● JFR should work - match allocations, method calls, etc. to virtual Threads ● Gaps in Thread API: ○ list all running threads ○ carrier <-> virtual thread Loom Debugging - Just regular!? wiki.openjdk.org/display/loom/Debugger+Support
  • 67. Loom Demos & Comparisions github.com/ebarlas Web-Backend Game of Life 5M persistent connections Elliot Barlas - MicroHttp - LogMeIn
  • 68. Performance Comparison Web-Server calling Backend github.com/ebarlas/project-loom-comparison
  • 69. WebServer ● Browser (ab) ● Web-Server calling ● 3x Backend (0,3s latency) ○ Authentication ○ Authorization ○ Database ● 3 implementations ○ Platform Threads ○ Asynchronous ○ Virtual Threads
  • 70. public void handle(Request request, Consumer<Response> callback) { executorService.execute(() -> callback.accept(doHandle(request))); } Response doHandle(Request request) { var token = request.header("Authorization"); var authentication = sendRequestFor("/authenticate?token=" + token, …); var authorization = sendRequestFor("/authorize?id=" + authentication.userId(), ..); var meetings = sendRequestFor("/meetings?id=" + authentication.userId(), …); var headers = List.of(new Header("Content-Type", "application/json")); return new Response(200, "OK", headers, Json.toJson(meetings)); } <T> T sendRequestFor(String endpoint, Class<T> type) throws IOException, InterruptedException { URI uri = URI.create("http://%s%s".formatted(backend, endpoint)); var request = HttpRequest.newBuilder().uri(uri).GET().build(); HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); if (response.statusCode() != 200) { throw new RuntimeException("error occurred contacting "+endpoint); } return Json.fromJson(response.body(), type); } Same old Executor (for both Platform & Virtual Threads)
  • 72. java --enable-preview -jar nima/target/example-nima-blocking.jar 2022.09.22 02:36:05.204 Logging at initialization configured using classpath: /logging.properties 2022.09.22 02:36:05.394 [0x6e82e640] http://127.0.0.1:8080 bound for socket '@default' 2022.09.22 02:36:05.396 [0x6e82e640] async writes, queue length: 32 2022.09.22 02:36:05.403 Níma server started all channels in 8 milliseconds. 244 milliseconds since JVM startup. Java 19+36-2238 ab -n 10000 -c 8 http://127.0.0.1:8080/one Concurrency Level: 8 Time taken for tests: 0.848 seconds Complete requests: 10000 Requests per second: 11797.14 [#/sec] (mean) Time per request: 0.678 [ms] (mean) Time per request: 0.085 [ms] (mean, across all concurrent requests) Transfer rate: 0.00 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 0 Processing: 0 0 0.0 0 0 Waiting: 0 0 0.0 0 0 Total: 0 0 0.0 0 1 Nima Test
  • 73. Helidon Nima Note: In either case, you should not “obstruct” the thread. Obstruction is a long-term, full utilization of the thread. In a reactive framework this would consume one of the event loop threads effectively stopping the server. In blocking (Níma) this may cause an issue with the “pinned thread”. In both cases this can be resolved by off-loading the heavy load to a dedicated executor service using platform threads.
  • 74. Performance comparable to Netty pipelined Note: What we can see from these numbers (and what is our goal with Níma) is that we can achieve performance comparable to a minimalist Netty server, while maintaining a simple, easy to use programming model.
  • 75. Game of Life CSP - Communicating Sequential Processes github.com/ebarlas/game-of-life-csp
  • 76. CSP - Not possible in Java before ● Channel (BlockingQueue<Boolean>) to exchange information ● Grid - Channel<boolean[][]> ● Each Cell has ○ a virtual thread ○ channels for ticks and results (width x height x 2) ○ one channel per neighbour (~ width x height x 8) ○ aka a LOT of channels/queues Wikipedia CSP
  • 77. Cell's biological Clock - "Life" private void run() { while (true) { tickChannel.take(); // wait for tick stimulus // announce liveness to neighbors outChannels.forEach(ch -> ch.put(alive)); // receive liveness from neighbors int neighbors = inChannels.stream() .map(Channel::take) .mapToInt(b -> b ? 1 : 0).sum(); // calculate next state based on game of life rules alive = alive && neighbors == 2 || neighbors == 3; // announce resulting next state resultChannel.put(alive); } } ● take / put -> block -> suspend ● exchange via channel/queue ● write only to local state
  • 78.
  • 79. Mario Fusco 🚀 Improved channel datastructures yield massive improvements speakerdeck.com/mariofusco Speaking Tour
  • 81. ● JEP 425 - Virtual Threads (Java 19) ● JEP 436 - Virtual Threads (Java 20) ● JEP 428 - Structured Concurrency ● JEP Café #12 - 10M Threads ● JEP Café #13 - Loom Tutorial ● Heinz Kabutz Loom Video ● JavaSpektrum Loom (me) ● Loom Lab (Nicolai Parlog) ● Million Virtual Threads ● Virtual Threads PR ● Loom Talk Pressler Bates Devoxx ● Loom Deep Dive: Paumard Forax Devoxx ● Loom Wiki ● Inside Java Loom ● Loom Networking under the Hood ● InfoQ Interview Ron Pressler ● State Of Loom Part 1 (Part 2) ● Helidon Nima ● Loom and Thread Fairness (Morling) ● Loom Comparison ● Structured Concurrency ● Mario Fusco: Game of Loom Resources
  • 82. A celebratory poem In threads of fate, a loom converged, A tapestry of change emerged, From distant shores, the world was swirled, As one, concurrent threads unfurled. -- courtesy GPT-4
  • 83. What can you do? Test! Provide feedback! Don't use in production (yet)!
  • 84. Thank You! … I'd love to take questions!