diff --git a/_shared/images/hosts/bettercode_java.png b/_shared/images/hosts/bettercode_java.png new file mode 100644 index 0000000..6112c4d Binary files /dev/null and b/_shared/images/hosts/bettercode_java.png differ diff --git a/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/example_class.svg.cache b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/example_class.svg.cache new file mode 100644 index 0000000..fd62a90 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/example_class.svg.cache @@ -0,0 +1 @@ +{"checksum":"03f9db8feb02c94feec00cf5b9e2bd31","options":{"css":null,"gantt_config":null,"seq_config":null,"width":null,"height":"400px","scale":null,"theme":null,"background":null,"config":null,"puppeteer_config":null},"width":173.90625,"height":320} \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/scoped_values_concept.svg.cache b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/scoped_values_concept.svg.cache new file mode 100644 index 0000000..5d25323 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/scoped_values_concept.svg.cache @@ -0,0 +1 @@ +{"checksum":"5dc7c6330e7b209358abfba77af8ed04","options":{"css":null,"gantt_config":null,"seq_config":null,"width":null,"height":"400px","scale":null,"theme":null,"background":null,"config":null,"puppeteer_config":null},"width":990,"height":521.2000122070312} \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/structured_concurrency_concept.svg.cache b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/structured_concurrency_concept.svg.cache new file mode 100644 index 0000000..bfa4b2a --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/structured_concurrency_concept.svg.cache @@ -0,0 +1 @@ +{"checksum":"016d3b1c7c3dc9031d369364afc39a1d","options":{"css":null,"gantt_config":null,"seq_config":null,"width":null,"height":"400px","scale":null,"theme":null,"background":null,"config":null,"puppeteer_config":null},"width":784,"height":244} \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_forking.svg.cache b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_forking.svg.cache new file mode 100644 index 0000000..739ba4f --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_forking.svg.cache @@ -0,0 +1 @@ +{"checksum":"0bf7289a01a9b39ec6d27af4277ac97a","options":{"css":null,"gantt_config":null,"seq_config":null,"width":null,"height":"400px","scale":null,"theme":null,"background":null,"config":null,"puppeteer_config":null},"width":null,"height":null} \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_normal.svg.cache b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_normal.svg.cache new file mode 100644 index 0000000..15f922e --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_normal.svg.cache @@ -0,0 +1 @@ +{"checksum":"38ded3ae12be03b0a1814841db9c5df9","options":{"css":null,"gantt_config":null,"seq_config":null,"width":null,"height":null,"scale":null,"theme":null,"background":null,"config":null,"puppeteer_config":null},"width":772.5,"height":401} \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_states.svg.cache b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_states.svg.cache new file mode 100644 index 0000000..03ebba7 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_states.svg.cache @@ -0,0 +1 @@ +{"checksum":"7ad8a38d51ce102cc3d70e028bd9093a","options":{"css":null,"gantt_config":null,"seq_config":null,"width":null,"height":"400px","scale":null,"theme":null,"background":null,"config":null,"puppeteer_config":null},"width":null,"height":null} \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_virtual.svg.cache b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_virtual.svg.cache new file mode 100644 index 0000000..3b4bf50 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/images/generated/thread_virtual.svg.cache @@ -0,0 +1 @@ +{"checksum":"76532fd170facae048459615f28e0552","options":{"layout":null},"width":340.48,"height":400.33000000000004} \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/thread_forking.svg.cache b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/thread_forking.svg.cache new file mode 100644 index 0000000..85d2a69 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/thread_forking.svg.cache @@ -0,0 +1 @@ +{"checksum":"887c043fc8032a96d03790a64f66fa4f","options":{"layout":null},"width":239.4,"height":352.45000000000005} \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/thread_states.svg.cache b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/thread_states.svg.cache new file mode 100644 index 0000000..8781613 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/.asciidoctor/diagram/thread_states.svg.cache @@ -0,0 +1 @@ +{"checksum":"cfc6003159fcc8b22aa196e938144038","options":{"layout":null},"width":525.35,"height":250.04000000000002} \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/images/AamCjmYS.jpg b/slides/2024-10-15-java23-concurrency-apis/images/AamCjmYS.jpg new file mode 100644 index 0000000..68db773 Binary files /dev/null and b/slides/2024-10-15-java23-concurrency-apis/images/AamCjmYS.jpg differ diff --git a/slides/2024-10-15-java23-concurrency-apis/images/SVT84DAs.jpg b/slides/2024-10-15-java23-concurrency-apis/images/SVT84DAs.jpg new file mode 100644 index 0000000..059fa21 Binary files /dev/null and b/slides/2024-10-15-java23-concurrency-apis/images/SVT84DAs.jpg differ diff --git a/slides/2024-10-15-java23-concurrency-apis/images/_sources.adoc b/slides/2024-10-15-java23-concurrency-apis/images/_sources.adoc new file mode 100644 index 0000000..6b6faf2 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/images/_sources.adoc @@ -0,0 +1,6 @@ +== Image Credits + +* Knited Speach Blubled generetd with https://deepai.org/gallery-item/e7ee5d480bed4d359b70607caf8b7f39/multiple-speech-bubbles-made-out-of-knited-wo_uKTYSNr.jpg.html[deepai.org] +* Virtual reality background generetd with https://deepai.org/gallery-item/7668458efa334d2081f1d41484319e6b/multiple-concurrent-actions-in-virtual-reality-3be37f.jpg.html[deepai.org] +* Elderly Person handing over treats generated with https://deepai.org/gallery-item/abec1ea3e0de460f9c5ac32b8128391c/elderly-person-handing-over-treats-to-todlers.jpg.html[deepai.org] +* Chaos of pipes and notations generated with https://deepai.org/gallery-item/3a428d1087004b27bb3caea2c0e7e0fd/a-chaos-of-pipes-that-contains-bpmn-notations.jpg.html[deepai.org] diff --git a/slides/2024-10-15-java23-concurrency-apis/images/dhhhSRjf.jpg b/slides/2024-10-15-java23-concurrency-apis/images/dhhhSRjf.jpg new file mode 100644 index 0000000..74b8577 Binary files /dev/null and b/slides/2024-10-15-java23-concurrency-apis/images/dhhhSRjf.jpg differ diff --git a/slides/2024-10-15-java23-concurrency-apis/images/generated/example_class.svg b/slides/2024-10-15-java23-concurrency-apis/images/generated/example_class.svg new file mode 100644 index 0000000..95779a4 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/images/generated/example_class.svg @@ -0,0 +1 @@ +
Engine
-SSLContext
-List<Rule>
+execute(Map data)
Rule
~readAddress()
~readName()
~fire()
\ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/images/generated/scoped_values_concept.svg b/slides/2024-10-15-java23-concurrency-apis/images/generated/scoped_values_concept.svg new file mode 100644 index 0000000..34abf32 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/images/generated/scoped_values_concept.svg @@ -0,0 +1 @@ +ThreadLocalT1sslCtx=0x01T2sslCtx=0x02ScopedValueT3sslCtx=0xA1T4sslCtx=0xA1 \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/images/generated/structured_concurrency_concept.svg b/slides/2024-10-15-java23-concurrency-apis/images/generated/structured_concurrency_concept.svg new file mode 100644 index 0000000..2251db4 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/images/generated/structured_concurrency_concept.svg @@ -0,0 +1 @@ +12:3012:3012:3012:3012:3112:3112:3112:3112:3212:32readAddress readName readAddress readName generateAnswer generateAnswer MerlinVanessa \ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_forking.svg b/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_forking.svg new file mode 100644 index 0000000..6a4b392 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_forking.svg @@ -0,0 +1 @@ +

Thread 1

Thread 2

Parent Thread

Birth and Death of Threads
\ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_normal.svg b/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_normal.svg new file mode 100644 index 0000000..a1250e7 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_normal.svg @@ -0,0 +1 @@ +
Task 1
Task 2
Task 3
Task 4

OSThread

Hardware CPU

Runable

Thread

OS Thread

Runable

Thread

OS Thread

Runable

Virtual Thread

Runable

Virtual Thread

\ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_states.svg b/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_states.svg new file mode 100644 index 0000000..4eb7ba9 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_states.svg @@ -0,0 +1 @@ +

New

Runable

Blocked

Waiting

Terminated

Lifecycle of a Thread
\ No newline at end of file diff --git a/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_virtual.svg b/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_virtual.svg new file mode 100644 index 0000000..b89bfc3 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/images/generated/thread_virtual.svg @@ -0,0 +1,86 @@ + + + +G + + +cluster_p1 + +Process 1 + + +cluster_p2 + +Process 2 + + + +CPU + + + + +CPU + + + +R3 + +Runable + + + +JT3 + +Virtual Thread + + + +R3->JT3 + + + + + +OST + +OS Thread + + + +JT3->OST + + + + + +R4 + +Runable + + + +JT4 + +Virtual Thread + + + +R4->JT4 + + + + + +JT4->OST + + + + + +OST->CPU + + + + + diff --git a/slides/2024-10-15-java23-concurrency-apis/images/wpEBCJQU.jpg b/slides/2024-10-15-java23-concurrency-apis/images/wpEBCJQU.jpg new file mode 100644 index 0000000..66d3596 Binary files /dev/null and b/slides/2024-10-15-java23-concurrency-apis/images/wpEBCJQU.jpg differ diff --git a/slides/2024-10-15-java23-concurrency-apis/index.html b/slides/2024-10-15-java23-concurrency-apis/index.html new file mode 100644 index 0000000..e7c0293 --- /dev/null +++ b/slides/2024-10-15-java23-concurrency-apis/index.html @@ -0,0 +1,856 @@ +Java 23: Mehr Handlung, mehr Übersicht

Java 23

Mehr Handlung, mehr Übersicht

+ + +
+ + +
+ +
+

Java Software Engineer

+

Line of Business Public

+
+
+
+
+ +
+ + +

+ Merlin Bögershausen + / @mboegie +

+
+
+ +
+

♻️ Recap on Threads ♻️

Threads in general

thread forking
+
thread states
+

Threads in Java

class ExampleThread extends Thread {
+  public void run() { /* Do it */}
+}
+var t1 = new ExampleThread();
+
+class ExampleRunable implements Runable {
+  public void run() { /* Do it again */}
+}
+var runable = new ExampleRunable();
+var t2 = new Thread(runable);
+
+t2.start(); t1.start();
+t2.join(); t1.join();
+

Concurrency Models [1]

ExecutorService

+
  • Thread Pool Management

  • reuse OS Threads

+

CompletableFuture

+
  • Composing asyncron operations

  • handling Results

+
1. Credits to Hanno Embregts on Devoxx.BE 2024, slides
+

JEP 444 Virtual Threads

Virtual threads are lightweight threads that improve Maintanace and Obervability.

Platform vs. Virtual

thread normal
+

Creation of Virtual

Thread.ofVirtual().start(() -> doIOStuffInParallel());
+
+Thread.ofPlatform() // is new as well
+

Better use Executors

Executors.newVirtualThreadPerTaskExecutor()
+	.submit(() -> doIOStuffInParallel());
+

Awesome, now what?

  • Lightweight?

  • Maintainabllility?

  • Oberservability?

+

Example we Work with

example class
+
+

JEP 481 Scoped Values

Share immutable data between callees within a thread and child threads.

Concept

scoped values concept
+

Goals of Scoped Values

  • 🥅 Ease of use

  • 🥅 Comprehensibility

  • 🥅 Robustness

  • 🥅 Performance

+

ScopesValues API

final static ScopedValue<SSLContext> VAL
+                    = ScopedValue.newInstance();
+
+ScopedValue.where(VAL, value)
+           .run(() -> VAL.get());
+
+ScopedValue.runWhere(VAL, value, () -> /* ... */);
+

Framework - Creation

private final static ScopedValue<Map<String, String>>
+    INPUTDATA = ScopedValue.newInstance();
+
+private final static ScopedValue<SSLContext>
+    SSL_CTX = ScopedValue.newInstance();

Framework -Config

ScopedValue.Carrier executionScope = ScopedValue
+    .where(INPUTDATA, Map.copyOf(data))
+    .where(SSL_CTX, SSLContext.getDefault());

Framework - Execution

// ScopedValue.Carrier executionScope;
+
+for (var r : rules) {
+    executionScope.run(r::fire);
+}

Usercode - Access I

//ScopedValue<Map<String, String>> INPUTDATA;
+
+String inputName = INPUTDATA
+        .orElseThrow(new IllegalArgumentException())
+        .getOrDefault("name", "JON");

Usercode - Access II

// ScopedValue<SSLContext> SSL_CTX
+
+if(SSL_CTX.isBound()) {
+    intputName = "%s %s".formatted(
+            inputName, getLastName(SSL_CTX.get()));
+}

Comparison [1]

ScopedValues

+
  • Immutable Carrier

  • Same instance

  • Rebindable

+

ThreadLocal

+
  • Supplier

  • Instance per Thread

  • Mutable Value

+
1. full length comparison by Alex Klimenko on Medium
+

JEP 480 Stuctured Concurrency

Treat groups of related tasks running in different threads as a single unit of work, thereby streamlining error handling and cancellation, improving reliability, and enhancing observability.

Concept

structured concurrency concept
+

Task Scope API

public class StructuredTaskScope<T> implements AutoCloseable {
+  public <U extends T> Subtask<U>
+        fork(Callable<? extends U> task);
+
+  public StructuredTaskScope<T> join()
+        throws InterruptedException;
+  public StructuredTaskScope<T> joinUntil(Instant deadline)
+        throws InterruptedException, TimeoutException;
+
+  public void shutdown();
+  public void close();
+}
+

Shutdown Policies

ShutdownOnFailure +first task failed

+

ShutdownOnSuccess +first task successfully terminates

Structured Concurrency in Rule

try (var scope = new StructuredTaskScope.ShutdownOnFailure()){
+    Supplier<String> adr = scope.fork(() -> readAddress());
+
+    scope.join().throwIfFailed();
+
+    var addres = adr.get();
+} catch (ExecutionException | InterruptedException e) {
+    throw new RuntimeException(e);
+}

Final words

  • Never pool VirtualThreads

  • Migrate immediately

  • ThreadLocal never mutated ⇒ ScopedValues

  • IO Concurrency ⇒ StructuredConcurrency

+

GitHub GIST with full code

+
+

Contact

+

Me

+MBoegie@fosstodon.org // +@MBoegi // +MBoegers +
+

adesso

+Infos // +DevBlog +

Approach direct

+I'm here all day with cookies!
+

Jobs

+
qrcode adesso jobs
+
+

Image Credits

  • Knited Speach Blubled generetd with deepai.org

  • Virtual reality background generetd with deepai.org

  • Elderly Person handing over treats generated with deepai.org

  • Chaos of pipes and notations generated with deepai.org

\ No newline at end of file