SlideShare ist ein Scribd-Unternehmen logo
1 von 69
Downloaden Sie, um offline zu lesen
Loom Virtual Threads in the JDK 19
José Paumard
Java Developer Advocate
Java Platform Group
https://twitter.com/JosePaumard
https://github.com/JosePaumard
https://www.youtube.com/user/java
https://www.youtube.com/user/JPaumard
https://www.youtube.com/c/coursenlignejava
https://www.youtube.com/hashtag/jepcafe
https://fr.slideshare.net/jpaumard
https://www.pluralsight.com/authors/jose-paumard
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
3
https://dev.java/
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
4
https://dev.java/community/
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
5
https://inside.java/
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
6
Don’t believe what I say!
Loom is a Preview Feature / Incubator API
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
7
Don’t believe what I say!
Loom is a Preview Feature / Incubator API
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
8
Don’t believe what I say!
Loom is a Preview Feature / Incubator API
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
9
Don’t believe what I say!
Loom is a Preview Feature / Incubator API
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
10
Don’t believe what I say!
Loom is a Preview Feature / Incubator API
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
11
Don’t believe what I say!
Loom is a Preview Feature / Incubator API
http://jdk.java.net/loom/
9/27/2022
Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted
12
It all Started with a Runnable

9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
13
1995: Thread, Runnable
1995: Threads and Runnables
Runnable task = new Runnable() {
void run() {
System.out.println("I am running in thread " +
Thread.currentThread().getName());
}
};
Thread thread = new Thread(task);
thread.start();
thread.join(); // blocks
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
14
1995: Thread, Runnable
1995: Threads and Runnables
Object key = new Object();
synchronized(key) {
System.out.println("Only one thread can execute me!");
}
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
15
2004: Java 5, java.util.concurrent
2004: Java Util Concurrent
Callable<String> task = new Callable<String>() {
@Override
public String call() throws Exception {
return "I am running in thread " +
Thread.currentThread().getName();
}
};
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
16
2004: Java 5, java.util.concurrent
Wait lists inside!
2004: Java Util Concurrent
ExecutorService service =
Executors.newFixedThreadPool(4);
Future<String> future = service.submit(task);
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
17
2004: Java 5, java.util.concurrent
2004: Java Util Concurrent
String result = future.get(); // blocks
String result = future.get(10, TimeUnit.MICROSECONDS);
boolean cancelled = future.cancel(true);
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
18
2004: Java 5, java.util.concurrent
2004: Java Util Concurrent
Lock lock = new ReentrantLock();
lock.lock();
try {
System.out.println("Only one thread can execute me!");
} finally {
lock.unlock();
}
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
19
2004: Java 5, java.util.concurrent
Plus many more concurrent classes:
- Lock, Semaphore, Barrier, CountDownLatch
- BlockingQueue, ConcurrentMap
- CopyOnWriteArrayList
2004: Java Util Concurrent
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
20
2011 – 2014 (Java 7, Java 8):
- Fork / Join, parallel Stream
Allows to compute elements in parallel
Two phases:
- fork = splits a task in two sub-tasks
- join = merge the result of two sub-tasks
Uses work stealing to spread the tasks among threads
2011: Fork / Join
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
21
2011 – 2014 (Java 7, Java 8):
- CompletionStage, CompletableFuture
Subtype of Future
Asynchronous programming model
Allows to trigger tasks on the outcome of other tasks
User can control which thread executes what task
Exceptions handling
2014: CompletionStage
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
22
Once a thread begins to process a task it cannot release it
Either the task completes with a result
Or is completes with an exception
It may be an InterruptedException
One thing stays the same
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
23
2022+ (prev. in Java 19)
2023?: Loom!
9/27/2022
Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted
24
Why Do We Need Concurrency?
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
25
Concurrency may be used in two different contexts:
1) Processing in-memory data in parallel, using all the CPU cores
- Each thread uses 100% of your CPU cores
- Threads are mostly not blocking
Concurrency: Computations vs. I/O
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
26
Concurrency may be used in two different contexts:
2) Handling numerous blocking requests / responses
HTTP Server  1 request <=|=> 1 thread
DB Server  1 transaction <=|=> 1 thread
Concurrency: Computations vs. I/O
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
27
Processing I/O data:
- Each task waits for the data it needs to process
Concurrency for I/O
Preparing the request
Time scale: 10ns
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
28
Processing I/O data:
- Each task waits for the data it needs to process
Concurrency for I/O
Waiting for the response
Time scale: 10ms
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
29
Processing I/O data:
- Each task waits for the data it needs to process
Concurrency for I/O
Processing the response
Time scale: 10ns
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
30
Processing I/O data:
A Thread is idle 99.9999% of the time!
How many threads do you need to keep your CPU busy?
Concurrency for I/O
ms ns
ns
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
31
A thread is not cheap!
- Thread startup time: ~1ms
- Thread memory consumption: 2MB of stack
- Context switching: ~100ms (depends on the OS)
Having 1 million platform threads is not possible!
Concurrency for I/O
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
32
CompletionState / CompletableFuture
Asynchronous / Reactive programming
Async / Await (C# or Kotlin)
Mono / Multi (Spring)
Uni / Multi (Quarkus)
Solutions?
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
33
Breaking down a request handling into small stages
Then compose them into a pipeline
The code becomes:
- hard to read and write (callback hell)
- hard to debug (call stack?)
- hard to test
- hard to profile
Solutions?
9/27/2022
Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted
34
Loom to the Rescue
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
35
Virtual Thread!
// platform threads
var pthread = new Thread(() -> {
System.out.println("platform " + Thread.currentThread());
});
pthread.start();
pthread.join();
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
36
Virtual Thread!
// virtual threads
var vthread = Thread.startVirtualThread(() -> {
System.out.println("virtual " + Thread.currentThread());
});
vthread.join();
// platform threads
var pthread = Thread.ofPlatform(() -> {
System.out.println("platform " + Thread.currentThread());
});
pthread.join();
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
37
A virtual thread runs on a carrier thread from a Fork-Join pool
(not the common fork join pool)
This pool implements a FIFO queue (instead of a LIFO one)
Virtual Thread!
// platform threads
platform Thread[#14,Thread-0,5,main]
// virtual threads
virtual VirtualThread[#15]/runnable@ForkJoinPool-1-worker-1
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
38
Thread Polymorphic Builder
// platform threads
var pthread = Thread.ofPlatform()
.name("platform-", 0)
.start(() -> {
System.out.println("platform " + Thread.currentThread());
});
pthread.join();
// virtual threads
var vthread = Thread.ofVirtual()
.name("virtual-", 0)
.start(() -> {
System.out.println("virtual " + Thread.currentThread());
});
vthread.join();
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
39
How many virtual threads can I run?
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
40
Platform/OS thread (starts in ms)
- Creates a 2MB stack upfront
- System call to ask the OS to schedule the thread
Virtual thread (starts in ÎŒs)
- Grow and shrink the stack dynamically
- Use a specific fork-join pool of platform threads (carrier
threads)
- One platform thread per core
Running a Thread
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
41
How does it work under the hood?
9/27/2022
Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted
42
Continuation
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
43
Example of Thread.sleep():
Calls Contination.yield()
Where Does the Magic Come From?
@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);
}
}
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
44
yield() copies the stack to the heap
Continuation.yield()
heap
stack
start()
Platform thread 1
sleep()
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
45
yield() copies the stack to the heap
Continuation.yield()
heap
stack
start()
Platform thread 1
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
46
run() copies from the heap to another stack
(optimization: only copies the topmost stack frames)
Continuation.run()
stack
start()
Platform thread 1
heap
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
47
run() copies from the heap to another stack
(optimization: only copies the topmost stack frames)
Continuation.run()
stack
start()
Platform thread 1
stack
Platform thread 2
heap
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
48
A Platform Thread is a thin wrapper on an OS Thread
A Virtual Thread is not tied to a particular OS Thread
A Virtual Thread only consumes an OS Thread
when it performs calculations on the CPU
Running a Virtual Thread
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
49
Creating a virtual thread is cheap
Blocking a virtual thread is cheap
Pooling virtual threads is useless
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
50
Most of the code of the virtual threads scheduling is written in
Java in the JDK (jdk.internal.vm.Continuation)
Written in C in the JVM:
- Copy of the stack frames back and forth
- GCs modified to find references in stack on heap
Loom is not Implemented « By the JVM »
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
51
All blocking codes are changed to
- Check if current thread is a virtual thread
- If it is, instead of blocking:
- Register a handler that will be called when the OS is
ready (using NIO)
- Call Continuation.yield()
- When the handler is called, find a carrier thread and call
Continuation.start()
In the JDK
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
52
Sometimes virtual threads are pinned to their carrier thread
Synchronized block are written in assembly and uses an address
on the stack
the stack frames can not be copied
Prefer ReentrantLock over synchronized()
There Are Cases Where It Does Not Work
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
53
Sometimes virtual threads are pinned to their carrier thread
Native code that does an upcall to Java may use an address on
stack
the stack frames can not be copied
There Are Cases Where It Does Not Work
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
54
Java 13
- JEP 353 Reimplement the Legacy Socket API
Java 14
- JEP 373 Reimplement the Legacy Datagram Socket API
- JEP 374 Deprecate and Disable Biased Locking
Stealth Rewrite of the JDK for Loom
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
55
Java 18
- JEP 416 Reimplement Core Reflection with Method Handles
- JEP 418 (Internet-Address Resolution SPI) in JDK 18 defined a
service-provider interface for host name and address lookup.
This will allow third-party libraries to implement alternative
java.net.InetAddress resolvers that do not pin threads during
host lookup
Stealth Rewrite of the JDK for Loom
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
56
The JDK creates as many virtual threads as the user want
- Mount a virtual thread to an available carrier thread when
starting
- If blocking, unmount the current virtual thread and mount
another virtual thread
Loom Idea: Under the Hood
9/27/2022
Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted
57
Structured Concurrency
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
58
The Travel Agency Example
Quotation
Weather Forecast
Travel Page
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
59
CompletableFuture Based Travel Agency
var quotationCF =
CompletableFuture.supplyAsync(() -> getQuotation());
var weatherCF =
CompletableFuture.supplyAsync(() -> getWeather());
CompletableFuture<Page> travelPageCF =
quotationCF
.exceptionally(t -> {
weatherCF.cancel(true);
throw new RuntimeException(t);
})
.thenCompose(
quotation -> weatherCF
// .completeOnTimeout(Weather.UNKNOWN, 100, MILLISECONDS)
.exceptionally(e -> Weather.UNKNOWN)
.thenApply(
weather ->
buildPage(quotation, weather)));
Quotation Server A
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
60
The Travel Agency Example
Quotation Server B
Quotation Server C
Weather Forecast Server A
Weather Forecast Server B
Weather Forecast Server C
Travel
Agency
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
61
CompletableFuture Based Travel Agency
var quotationCF =
CompletableFuture.supplyAsync(() -> getQuotation());
var weatherCF =
CompletableFuture.supplyAsync(() -> getWeather());
CompletableFuture<Page> travelPageCF =
quotationCF
.exceptionally(t -> {
weatherCF.cancel(true);
throw new RuntimeException(t);
})
.thenCompose(
quotation -> weatherCF
// .completeOnTimeout(Weather.UNKNOWN, 100, MILLISECONDS)
.exceptionally(e -> Weather.UNKNOWN)
.thenApply(
weather ->
buildPage(quotation, weather)));
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
62
Stuctured Concurrency Based Travel Agency
try (var scope = new WeatherScope()) {
scope.fork(() -> readWeatherFromA());
scope.fork(() -> readWeatherFromB());
scope.fork(() -> readWeatherFromC());
scope.join();
Weather firstWeather = scope.getFirstWeather();
return firstWeather;
}
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
63
Stuctured Concurrency Based Travel Agency
try (var scope = new QuotationScope()) {
scope.fork(() -> readQuotationFromA());
scope.fork(() -> readQuotationFromB());
scope.fork(() -> readQuotationFromC();
scope.join();
Quotation bestQuotation = scope.getBestQuotation();
return bestQuotation;
}
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
64
Stuctured Concurrency Based Travel Agency
try (var scope = new TravelPageScope()) {
scope.fork(() -> getFirstWeather());
scope.fork(() -> getBestQuotation());
scope.join();
TravelPage page = scope.buildTravelPage();
return page;
}
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
65
Stuctured Concurrency Based Travel Agency
protected void handleComplete(Future<Quotation> future) {
switch (future.state()) {
case RUNNING -> throw new IllegalStateException("Ooops");
case SUCCESS -> this.quotations.add(future.resultNow());
case FAILED -> this.exceptions.add(future.exceptionNow());
case CANCELLED -> { }
}
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
66
Stuctured Concurrency Based Travel Agency
public Quotation bestQuotation() {
return this.quotations.stream()
.min(Comparator.comparing(Quotation::quotation))
.orElseThrow(this::exceptions);
}
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
67
Stuctured Concurrency Based Travel Agency
public QuotationException exceptions() {
QuotationException exception = new QuotationException();
this.exceptions.forEach(exception::addSuppressed);
return exception;
}
9/27/2022
Copyright © 2021, Oracle and/or its affiliates |
68
Leveraging this million threads
Leveraging virtual threads, « free » to create / block
Write simple, imperative, mono-thread code
Easy to read, easy to test, easy to debug
Stuctured Concurrency in Three Words
Loom is Great!

Weitere Àhnliche Inhalte

Was ist angesagt?

Mocking in Java with Mockito
Mocking in Java with MockitoMocking in Java with Mockito
Mocking in Java with Mockito
Richard Paul
 

Was ist angesagt? (20)

Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New Features
 
Reactive programming intro
Reactive programming introReactive programming intro
Reactive programming intro
 
Java 8-streams-collectors-patterns
Java 8-streams-collectors-patternsJava 8-streams-collectors-patterns
Java 8-streams-collectors-patterns
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Loom promises: be there!
Loom promises: be there!Loom promises: be there!
Loom promises: be there!
 
Discover Quarkus and GraalVM
Discover Quarkus and GraalVMDiscover Quarkus and GraalVM
Discover Quarkus and GraalVM
 
clicks2conversations.pdf
clicks2conversations.pdfclicks2conversations.pdf
clicks2conversations.pdf
 
Mocking in Java with Mockito
Mocking in Java with MockitoMocking in Java with Mockito
Mocking in Java with Mockito
 
Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)Making The Move To Java 17 (JConf 2022)
Making The Move To Java 17 (JConf 2022)
 
kafka
kafkakafka
kafka
 
Completable future
Completable futureCompletable future
Completable future
 
Reactive Programming In Java Using: Project Reactor
Reactive Programming In Java Using: Project ReactorReactive Programming In Java Using: Project Reactor
Reactive Programming In Java Using: Project Reactor
 
Common issues with Apache KafkaÂź Producer
Common issues with Apache KafkaÂź ProducerCommon issues with Apache KafkaÂź Producer
Common issues with Apache KafkaÂź Producer
 
Spring data jpa
Spring data jpaSpring data jpa
Spring data jpa
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 
GraalVm and Quarkus
GraalVm and QuarkusGraalVm and Quarkus
GraalVm and Quarkus
 
API Asynchrones en Java 8
API Asynchrones en Java 8API Asynchrones en Java 8
API Asynchrones en Java 8
 
GraalVM: Run Programs Faster Everywhere
GraalVM: Run Programs Faster EverywhereGraalVM: Run Programs Faster Everywhere
GraalVM: Run Programs Faster Everywhere
 
Introduction to GraalVM
Introduction to GraalVMIntroduction to GraalVM
Introduction to GraalVM
 
Reactive programming
Reactive programmingReactive programming
Reactive programming
 

Ähnlich wie Loom Virtual Threads in the JDK 19

Ähnlich wie Loom Virtual Threads in the JDK 19 (20)

Java Cloud and Container Ready
Java Cloud and Container ReadyJava Cloud and Container Ready
Java Cloud and Container Ready
 
Node.js and Oracle Database: New Development Techniques
Node.js and Oracle Database: New Development TechniquesNode.js and Oracle Database: New Development Techniques
Node.js and Oracle Database: New Development Techniques
 
Java 40 versions_sgp
Java 40 versions_sgpJava 40 versions_sgp
Java 40 versions_sgp
 
Hotspot & AOT
Hotspot & AOTHotspot & AOT
Hotspot & AOT
 
Serverless Java Challenges & Triumphs
Serverless Java Challenges & TriumphsServerless Java Challenges & Triumphs
Serverless Java Challenges & Triumphs
 
Oracle Cloud Infrastructure2020ćčŽ8月ćșŠă‚”ăƒŒăƒ“ă‚čăƒ»ă‚ąăƒƒăƒ—ăƒ‡ăƒŒăƒˆ
Oracle Cloud Infrastructure2020ćčŽ8月ćșŠă‚”ăƒŒăƒ“ă‚čăƒ»ă‚ąăƒƒăƒ—ăƒ‡ăƒŒăƒˆOracle Cloud Infrastructure2020ćčŽ8月ćșŠă‚”ăƒŒăƒ“ă‚čăƒ»ă‚ąăƒƒăƒ—ăƒ‡ăƒŒăƒˆ
Oracle Cloud Infrastructure2020ćčŽ8月ćșŠă‚”ăƒŒăƒ“ă‚čăƒ»ă‚ąăƒƒăƒ—ăƒ‡ăƒŒăƒˆ
 
Serverless Java: JJUG CCC 2019
Serverless Java: JJUG CCC 2019Serverless Java: JJUG CCC 2019
Serverless Java: JJUG CCC 2019
 
MySQL Database Architectures - 2022-08
MySQL Database Architectures - 2022-08MySQL Database Architectures - 2022-08
MySQL Database Architectures - 2022-08
 
"Quantum" Performance Effects
"Quantum" Performance Effects"Quantum" Performance Effects
"Quantum" Performance Effects
 
Oracle CloudWorld 2023 - How to hook up Telegram with Spring Boot and ADB
Oracle CloudWorld 2023 - How to hook up Telegram with Spring Boot and ADBOracle CloudWorld 2023 - How to hook up Telegram with Spring Boot and ADB
Oracle CloudWorld 2023 - How to hook up Telegram with Spring Boot and ADB
 
Compile ahead of time. It's fine?
Compile ahead of time. It's fine?Compile ahead of time. It's fine?
Compile ahead of time. It's fine?
 
Spring Boot 3 And Beyond
Spring Boot 3 And BeyondSpring Boot 3 And Beyond
Spring Boot 3 And Beyond
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS Meetup
 
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
 
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
Multiplatform shared codebase with Kotlin/Native - UA Mobile 2019
 
Jakarta EE æœ€ć‰ç·š - Jakarta EEăźçŸćœšă€ăƒ­ăƒŒăƒ‰ăƒžăƒƒăƒ—ăȘど
Jakarta EE æœ€ć‰ç·š - Jakarta EEăźçŸćœšă€ăƒ­ăƒŒăƒ‰ăƒžăƒƒăƒ—ăȘどJakarta EE æœ€ć‰ç·š - Jakarta EEăźçŸćœšă€ăƒ­ăƒŒăƒ‰ăƒžăƒƒăƒ—ăȘど
Jakarta EE æœ€ć‰ç·š - Jakarta EEăźçŸćœšă€ăƒ­ăƒŒăƒ‰ăƒžăƒƒăƒ—ăȘど
 
Java programming concept
Java programming conceptJava programming concept
Java programming concept
 
Building Large Java Projects Faster: Multicore javac and Makefile integration
Building Large Java Projects Faster: Multicore javac and Makefile integrationBuilding Large Java Projects Faster: Multicore javac and Makefile integration
Building Large Java Projects Faster: Multicore javac and Makefile integration
 
Java is Container Ready - Vaibhav - Container Conference 2018
Java is Container Ready - Vaibhav - Container Conference 2018Java is Container Ready - Vaibhav - Container Conference 2018
Java is Container Ready - Vaibhav - Container Conference 2018
 
DesktopApps.pptx
DesktopApps.pptxDesktopApps.pptx
DesktopApps.pptx
 

Mehr von José Paumard

Mehr von José Paumard (20)

Designing functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patternsDesigning functional and fluent API: application to some GoF patterns
Designing functional and fluent API: application to some GoF patterns
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
The Sincerest Form of Flattery
The Sincerest Form of FlatteryThe Sincerest Form of Flattery
The Sincerest Form of Flattery
 
Designing functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor PatternDesigning functional and fluent API: example of the Visitor Pattern
Designing functional and fluent API: example of the Visitor Pattern
 
Construire son JDK en 10 Ă©tapes
Construire son JDK en 10 Ă©tapesConstruire son JDK en 10 Ă©tapes
Construire son JDK en 10 Ă©tapes
 
Java Keeps Throttling Up!
Java Keeps Throttling Up!Java Keeps Throttling Up!
Java Keeps Throttling Up!
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
 
Asynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowAsynchronous Systems with Fn Flow
Asynchronous Systems with Fn Flow
 
Java Full Throttle
Java Full ThrottleJava Full Throttle
Java Full Throttle
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
 
Collectors in the Wild
Collectors in the WildCollectors in the Wild
Collectors in the Wild
 
Streams in the wild
Streams in the wildStreams in the wild
Streams in the wild
 
JAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridgeJAX RS and CDI bike the reactive bridge
JAX RS and CDI bike the reactive bridge
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
L'API Collector dans tous ses Ă©tats
L'API Collector dans tous ses Ă©tatsL'API Collector dans tous ses Ă©tats
L'API Collector dans tous ses Ă©tats
 
Linked to ArrayList: the full story
Linked to ArrayList: the full storyLinked to ArrayList: the full story
Linked to ArrayList: the full story
 
Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
ArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateauArrayList et LinkedList sont dans un bateau
ArrayList et LinkedList sont dans un bateau
 
Java SE 8 for Java EE developers
Java SE 8 for Java EE developersJava SE 8 for Java EE developers
Java SE 8 for Java EE developers
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
 

KĂŒrzlich hochgeladen

Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
ZurliaSoop
 

KĂŒrzlich hochgeladen (20)

Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.ppt
 
ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.
 
REMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptxREMIFENTANIL: An Ultra short acting opioid.pptx
REMIFENTANIL: An Ultra short acting opioid.pptx
 
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
NO1 Top Black Magic Specialist In Lahore Black magic In Pakistan Kala Ilam Ex...
 
Sociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning ExhibitSociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning Exhibit
 
Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)Jamworks pilot and AI at Jisc (20/03/2024)
Jamworks pilot and AI at Jisc (20/03/2024)
 
Micro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdfMicro-Scholarship, What it is, How can it help me.pdf
Micro-Scholarship, What it is, How can it help me.pdf
 
Mehran University Newsletter Vol-X, Issue-I, 2024
Mehran University Newsletter Vol-X, Issue-I, 2024Mehran University Newsletter Vol-X, Issue-I, 2024
Mehran University Newsletter Vol-X, Issue-I, 2024
 
Fostering Friendships - Enhancing Social Bonds in the Classroom
Fostering Friendships - Enhancing Social Bonds  in the ClassroomFostering Friendships - Enhancing Social Bonds  in the Classroom
Fostering Friendships - Enhancing Social Bonds in the Classroom
 
Understanding Accommodations and Modifications
Understanding  Accommodations and ModificationsUnderstanding  Accommodations and Modifications
Understanding Accommodations and Modifications
 
Google Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptxGoogle Gemini An AI Revolution in Education.pptx
Google Gemini An AI Revolution in Education.pptx
 
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptxOn_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
On_Translating_a_Tamil_Poem_by_A_K_Ramanujan.pptx
 
How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17How to Give a Domain for a Field in Odoo 17
How to Give a Domain for a Field in Odoo 17
 
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptxHMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
HMCS Vancouver Pre-Deployment Brief - May 2024 (Web Version).pptx
 
Interdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptxInterdisciplinary_Insights_Data_Collection_Methods.pptx
Interdisciplinary_Insights_Data_Collection_Methods.pptx
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan Fellows
 
Python Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docxPython Notes for mca i year students osmania university.docx
Python Notes for mca i year students osmania university.docx
 
SOC 101 Demonstration of Learning Presentation
SOC 101 Demonstration of Learning PresentationSOC 101 Demonstration of Learning Presentation
SOC 101 Demonstration of Learning Presentation
 
General Principles of Intellectual Property: Concepts of Intellectual Proper...
General Principles of Intellectual Property: Concepts of Intellectual  Proper...General Principles of Intellectual Property: Concepts of Intellectual  Proper...
General Principles of Intellectual Property: Concepts of Intellectual Proper...
 
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
Jual Obat Aborsi Hongkong ( Asli No.1 ) 085657271886 Obat Penggugur Kandungan...
 

Loom Virtual Threads in the JDK 19

  • 1. Loom Virtual Threads in the JDK 19 JosĂ© Paumard Java Developer Advocate Java Platform Group
  • 3. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 3 https://dev.java/
  • 4. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 4 https://dev.java/community/
  • 5. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 5 https://inside.java/
  • 6. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 6 Don’t believe what I say! Loom is a Preview Feature / Incubator API
  • 7. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 7 Don’t believe what I say! Loom is a Preview Feature / Incubator API
  • 8. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 8 Don’t believe what I say! Loom is a Preview Feature / Incubator API
  • 9. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 9 Don’t believe what I say! Loom is a Preview Feature / Incubator API
  • 10. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 10 Don’t believe what I say! Loom is a Preview Feature / Incubator API
  • 11. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 11 Don’t believe what I say! Loom is a Preview Feature / Incubator API http://jdk.java.net/loom/
  • 12. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 12 It all Started with a Runnable

  • 13. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 13 1995: Thread, Runnable 1995: Threads and Runnables Runnable task = new Runnable() { void run() { System.out.println("I am running in thread " + Thread.currentThread().getName()); } }; Thread thread = new Thread(task); thread.start(); thread.join(); // blocks
  • 14. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 14 1995: Thread, Runnable 1995: Threads and Runnables Object key = new Object(); synchronized(key) { System.out.println("Only one thread can execute me!"); }
  • 15. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 15 2004: Java 5, java.util.concurrent 2004: Java Util Concurrent Callable<String> task = new Callable<String>() { @Override public String call() throws Exception { return "I am running in thread " + Thread.currentThread().getName(); } };
  • 16. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 16 2004: Java 5, java.util.concurrent Wait lists inside! 2004: Java Util Concurrent ExecutorService service = Executors.newFixedThreadPool(4); Future<String> future = service.submit(task);
  • 17. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 17 2004: Java 5, java.util.concurrent 2004: Java Util Concurrent String result = future.get(); // blocks String result = future.get(10, TimeUnit.MICROSECONDS); boolean cancelled = future.cancel(true);
  • 18. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 18 2004: Java 5, java.util.concurrent 2004: Java Util Concurrent Lock lock = new ReentrantLock(); lock.lock(); try { System.out.println("Only one thread can execute me!"); } finally { lock.unlock(); }
  • 19. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 19 2004: Java 5, java.util.concurrent Plus many more concurrent classes: - Lock, Semaphore, Barrier, CountDownLatch - BlockingQueue, ConcurrentMap - CopyOnWriteArrayList 2004: Java Util Concurrent
  • 20. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 20 2011 – 2014 (Java 7, Java 8): - Fork / Join, parallel Stream Allows to compute elements in parallel Two phases: - fork = splits a task in two sub-tasks - join = merge the result of two sub-tasks Uses work stealing to spread the tasks among threads 2011: Fork / Join
  • 21. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 21 2011 – 2014 (Java 7, Java 8): - CompletionStage, CompletableFuture Subtype of Future Asynchronous programming model Allows to trigger tasks on the outcome of other tasks User can control which thread executes what task Exceptions handling 2014: CompletionStage
  • 22. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 22 Once a thread begins to process a task it cannot release it Either the task completes with a result Or is completes with an exception It may be an InterruptedException One thing stays the same
  • 23. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 23 2022+ (prev. in Java 19) 2023?: Loom!
  • 24. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 24 Why Do We Need Concurrency?
  • 25. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 25 Concurrency may be used in two different contexts: 1) Processing in-memory data in parallel, using all the CPU cores - Each thread uses 100% of your CPU cores - Threads are mostly not blocking Concurrency: Computations vs. I/O
  • 26. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 26 Concurrency may be used in two different contexts: 2) Handling numerous blocking requests / responses HTTP Server  1 request <=|=> 1 thread DB Server  1 transaction <=|=> 1 thread Concurrency: Computations vs. I/O
  • 27. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 27 Processing I/O data: - Each task waits for the data it needs to process Concurrency for I/O Preparing the request Time scale: 10ns
  • 28. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 28 Processing I/O data: - Each task waits for the data it needs to process Concurrency for I/O Waiting for the response Time scale: 10ms
  • 29. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 29 Processing I/O data: - Each task waits for the data it needs to process Concurrency for I/O Processing the response Time scale: 10ns
  • 30. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 30 Processing I/O data: A Thread is idle 99.9999% of the time! How many threads do you need to keep your CPU busy? Concurrency for I/O ms ns ns
  • 31. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 31 A thread is not cheap! - Thread startup time: ~1ms - Thread memory consumption: 2MB of stack - Context switching: ~100ms (depends on the OS) Having 1 million platform threads is not possible! Concurrency for I/O
  • 32. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 32 CompletionState / CompletableFuture Asynchronous / Reactive programming Async / Await (C# or Kotlin) Mono / Multi (Spring) Uni / Multi (Quarkus) Solutions?
  • 33. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 33 Breaking down a request handling into small stages Then compose them into a pipeline The code becomes: - hard to read and write (callback hell) - hard to debug (call stack?) - hard to test - hard to profile Solutions?
  • 34. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 34 Loom to the Rescue
  • 35. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 35 Virtual Thread! // platform threads var pthread = new Thread(() -> { System.out.println("platform " + Thread.currentThread()); }); pthread.start(); pthread.join();
  • 36. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 36 Virtual Thread! // virtual threads var vthread = Thread.startVirtualThread(() -> { System.out.println("virtual " + Thread.currentThread()); }); vthread.join(); // platform threads var pthread = Thread.ofPlatform(() -> { System.out.println("platform " + Thread.currentThread()); }); pthread.join();
  • 37. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 37 A virtual thread runs on a carrier thread from a Fork-Join pool (not the common fork join pool) This pool implements a FIFO queue (instead of a LIFO one) Virtual Thread! // platform threads platform Thread[#14,Thread-0,5,main] // virtual threads virtual VirtualThread[#15]/runnable@ForkJoinPool-1-worker-1
  • 38. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 38 Thread Polymorphic Builder // platform threads var pthread = Thread.ofPlatform() .name("platform-", 0) .start(() -> { System.out.println("platform " + Thread.currentThread()); }); pthread.join(); // virtual threads var vthread = Thread.ofVirtual() .name("virtual-", 0) .start(() -> { System.out.println("virtual " + Thread.currentThread()); }); vthread.join();
  • 39. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 39 How many virtual threads can I run?
  • 40. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 40 Platform/OS thread (starts in ms) - Creates a 2MB stack upfront - System call to ask the OS to schedule the thread Virtual thread (starts in ÎŒs) - Grow and shrink the stack dynamically - Use a specific fork-join pool of platform threads (carrier threads) - One platform thread per core Running a Thread
  • 41. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 41 How does it work under the hood?
  • 42. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 42 Continuation
  • 43. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 43 Example of Thread.sleep(): Calls Contination.yield() Where Does the Magic Come From? @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); } }
  • 44. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 44 yield() copies the stack to the heap Continuation.yield() heap stack start() Platform thread 1 sleep()
  • 45. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 45 yield() copies the stack to the heap Continuation.yield() heap stack start() Platform thread 1
  • 46. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 46 run() copies from the heap to another stack (optimization: only copies the topmost stack frames) Continuation.run() stack start() Platform thread 1 heap
  • 47. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 47 run() copies from the heap to another stack (optimization: only copies the topmost stack frames) Continuation.run() stack start() Platform thread 1 stack Platform thread 2 heap
  • 48. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 48 A Platform Thread is a thin wrapper on an OS Thread A Virtual Thread is not tied to a particular OS Thread A Virtual Thread only consumes an OS Thread when it performs calculations on the CPU Running a Virtual Thread
  • 49. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 49 Creating a virtual thread is cheap Blocking a virtual thread is cheap Pooling virtual threads is useless
  • 50. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 50 Most of the code of the virtual threads scheduling is written in Java in the JDK (jdk.internal.vm.Continuation) Written in C in the JVM: - Copy of the stack frames back and forth - GCs modified to find references in stack on heap Loom is not Implemented « By the JVM »
  • 51. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 51 All blocking codes are changed to - Check if current thread is a virtual thread - If it is, instead of blocking: - Register a handler that will be called when the OS is ready (using NIO) - Call Continuation.yield() - When the handler is called, find a carrier thread and call Continuation.start() In the JDK
  • 52. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 52 Sometimes virtual threads are pinned to their carrier thread Synchronized block are written in assembly and uses an address on the stack the stack frames can not be copied Prefer ReentrantLock over synchronized() There Are Cases Where It Does Not Work
  • 53. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 53 Sometimes virtual threads are pinned to their carrier thread Native code that does an upcall to Java may use an address on stack the stack frames can not be copied There Are Cases Where It Does Not Work
  • 54. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 54 Java 13 - JEP 353 Reimplement the Legacy Socket API Java 14 - JEP 373 Reimplement the Legacy Datagram Socket API - JEP 374 Deprecate and Disable Biased Locking Stealth Rewrite of the JDK for Loom
  • 55. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 55 Java 18 - JEP 416 Reimplement Core Reflection with Method Handles - JEP 418 (Internet-Address Resolution SPI) in JDK 18 defined a service-provider interface for host name and address lookup. This will allow third-party libraries to implement alternative java.net.InetAddress resolvers that do not pin threads during host lookup Stealth Rewrite of the JDK for Loom
  • 56. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 56 The JDK creates as many virtual threads as the user want - Mount a virtual thread to an available carrier thread when starting - If blocking, unmount the current virtual thread and mount another virtual thread Loom Idea: Under the Hood
  • 57. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | Confidential: Internal/Restricted/Highly Restricted 57 Structured Concurrency
  • 58. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 58 The Travel Agency Example Quotation Weather Forecast Travel Page
  • 59. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 59 CompletableFuture Based Travel Agency var quotationCF = CompletableFuture.supplyAsync(() -> getQuotation()); var weatherCF = CompletableFuture.supplyAsync(() -> getWeather()); CompletableFuture<Page> travelPageCF = quotationCF .exceptionally(t -> { weatherCF.cancel(true); throw new RuntimeException(t); }) .thenCompose( quotation -> weatherCF // .completeOnTimeout(Weather.UNKNOWN, 100, MILLISECONDS) .exceptionally(e -> Weather.UNKNOWN) .thenApply( weather -> buildPage(quotation, weather)));
  • 60. Quotation Server A 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 60 The Travel Agency Example Quotation Server B Quotation Server C Weather Forecast Server A Weather Forecast Server B Weather Forecast Server C Travel Agency
  • 61. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 61 CompletableFuture Based Travel Agency var quotationCF = CompletableFuture.supplyAsync(() -> getQuotation()); var weatherCF = CompletableFuture.supplyAsync(() -> getWeather()); CompletableFuture<Page> travelPageCF = quotationCF .exceptionally(t -> { weatherCF.cancel(true); throw new RuntimeException(t); }) .thenCompose( quotation -> weatherCF // .completeOnTimeout(Weather.UNKNOWN, 100, MILLISECONDS) .exceptionally(e -> Weather.UNKNOWN) .thenApply( weather -> buildPage(quotation, weather)));
  • 62. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 62 Stuctured Concurrency Based Travel Agency try (var scope = new WeatherScope()) { scope.fork(() -> readWeatherFromA()); scope.fork(() -> readWeatherFromB()); scope.fork(() -> readWeatherFromC()); scope.join(); Weather firstWeather = scope.getFirstWeather(); return firstWeather; }
  • 63. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 63 Stuctured Concurrency Based Travel Agency try (var scope = new QuotationScope()) { scope.fork(() -> readQuotationFromA()); scope.fork(() -> readQuotationFromB()); scope.fork(() -> readQuotationFromC(); scope.join(); Quotation bestQuotation = scope.getBestQuotation(); return bestQuotation; }
  • 64. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 64 Stuctured Concurrency Based Travel Agency try (var scope = new TravelPageScope()) { scope.fork(() -> getFirstWeather()); scope.fork(() -> getBestQuotation()); scope.join(); TravelPage page = scope.buildTravelPage(); return page; }
  • 65. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 65 Stuctured Concurrency Based Travel Agency protected void handleComplete(Future<Quotation> future) { switch (future.state()) { case RUNNING -> throw new IllegalStateException("Ooops"); case SUCCESS -> this.quotations.add(future.resultNow()); case FAILED -> this.exceptions.add(future.exceptionNow()); case CANCELLED -> { } }
  • 66. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 66 Stuctured Concurrency Based Travel Agency public Quotation bestQuotation() { return this.quotations.stream() .min(Comparator.comparing(Quotation::quotation)) .orElseThrow(this::exceptions); }
  • 67. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 67 Stuctured Concurrency Based Travel Agency public QuotationException exceptions() { QuotationException exception = new QuotationException(); this.exceptions.forEach(exception::addSuppressed); return exception; }
  • 68. 9/27/2022 Copyright © 2021, Oracle and/or its affiliates | 68 Leveraging this million threads Leveraging virtual threads, « free » to create / block Write simple, imperative, mono-thread code Easy to read, easy to test, easy to debug Stuctured Concurrency in Three Words