[2024 dev2next] virtual threads

Speaker: Piotr Przybyl @piotrprz and @piotrprz@mstdn.social

For more see the table of contents


Note: some things in this talk are in preview features. Might change/get better

Demo

  • Traditional demo of starting a thread and having it wait 10 seconds.
  • Ran 1K platform threads in just over 10 seconds. Ran 30K in 15 seconds. Ran 40K and it crashed due to “not enough space”.
  • Switched to virtual threads and no more resource constraints. Just over 10 seconds for 40K virtual threads. A million virtual threads took about 15 seconds
  • Awesome until see how fooled by demo
  • In the demo is sleeping, not using any resources
  • Redid demo with CPU work so no blocking.

Releases

  • released in Java 21 and previewed in 20-21
  • structured concurrency – preview in 23
  • Scoped values – preview in 22

Virtual threads

  • Great for I/O and waiting
  • No way to switch on and off globally in JDK
  • Don’t make threads faster; Make app scale better
  • Gave NYC example: drive to restaurant and park. Hardware resource (Car) not used. Vs taxi/Uber where don’t care where is when eating
  • If all cars were taxis, could move people faster. But one person doesn’t move faster by just using a taxi.
  • Said not his metaphor but likes it [I like it too]
  • Will not squeeze more juice from your CPU

Don’t Reuse

  • Reuse – cheap to start, create new
  • Pool – requires reusing

Don’t Pin

  • Like car “keep engine running”. Wastes resources, still have to pay.
  • I/O and synchronize pin in Java 21 when takes more than 20ms
  • Find with -Djdk.tracePinnedThreads=full and JFR events
  • toxiproxy – good for chaos engineering. Can set to half a second plus some jitter for variance (or anything you want)

Logging Double slit experiment – “how many lights are there”

  • Observing makes the answer different
  • Changed from 5 seconds of work to five one seconds and added logging.
  • Logging changing behavior because default handler is synchronous.
  • Less finished because opportunities for other threads to get in
  • It’s like everyone calling an Uber when a concert gets out.
  • Every time you do I/O, the thread blocks. ex: get out of taxi
  • Platform threads are different; they don’t block just because you do an I/O operation.

Other problems

  • Can’t ignore backpressure control
  • Ignore interrupts
  • merge with synchronized/native

Structured Concurrency (preview)

  • better “idioms” for multi threaded coded
  • helps eliminate thread leaks and cancellation delays
  • not replacing interruption with cancellation
  • showed waiting on two future. they don’t know the other gave up.
  • each future needs a reference to all other features so they know to give up when implemented manually
  • StructuredTaskScope.ShutdownOnFailure() { // two futures } // allows to know
  • scope.throwIfFailed() knows

Scoped Values (preview)

  • One way immutable ThreadLocals.
  • ThreadLocale is like a cache.
  • Bounded lifetime; visible in code
  • Results in simplified reasoning and improved performance
  • ScopedValue.where(x,y). run(() -> dostuff())
  • Can use Runnable or Callable
  • Can nest where() as long as you don’t mutate it

My take

This was interesting. I didn’t know pinned threads were a thing. Also good humor; well known debug pattern of “debug 1” 🙂

[uberconf 2023] Structured Concurrency in Java

Speaker: Venkat Subramaniam

@venkat_s

For more, see the table of contents


Warning

  • Incubator phase feature
  • Anything can change.
  • Will be a year or more before release
  • use –enable-preview flag
  • Java prints out warning using incubator feature whenever run program

Executor Service

  • Since Java 5
  • Executors.newFixedThreadPool(x)
  • executorService.submit() -> logic()) – returns future. Call future.get() when done
  • executorService.shutdown()
  • executorService.awaitTermination(10, TImeout.SECONDS)

Structured Concurrency

  • Allow control of what happens on parallel
  • Parent handles/processes failures from children
  • Currently import jdk.incubator.concurrent – will move
  • StructuredTaskScopeShutdownOnFailure – invoke all
  • StructuredTaskScopeShutdownOnSuccess – invoke any
  • try (var scope = new StructuredTaskScope()) – want autoclose – or scope = StructuredTaskScopeShutdownOnSuccess() or scope = StructuredTaskScopeShutdownOnSuccess<String>()
  • scope.fork(() -> logic()) – makes child tasks, still returns a Future
  • scope.join() – don’t use – better to use a timeout so not unbounded waiting on children
  • scope.joinUntil(Instant.now().plusSeconds(50)) – better, uses timeout. waits for all children up to timeout Nice using Java date math
  • future.resultNow() – get result immediately. (vs get() which waits if not available)
  • scope.throwIfFailed(ex- > handle()) – deal with first failure

Scoped Values

  • ThreadLocal not useful in Spring because thread executing code not the same one that created the value
  • Scoped value, not scoped variable. Immutable
  • Hide the value instead of changing it
  • New value available in inner value. When get back out of that scope, see original value.
  • Doesn’t matter which thread runs the code because matters where you are in code.
  • Useful when calling a lambda which does a callback via third party code
  • Created ScopedValue field in the class that needs the data.
  • ScopedValue.newInstance() – placeholder, doesn’t have value yet
  • state.isBound() – whether has been set to a value
  • ScopedValue.where(state, “test”).run(lamba) – binds the value
  • state.get() – get value if bound. Blows up if not bound

My take

As an incubator feature, I knew nothing about this. It was great to learn about it from a Venkat talk. Different then the usual which is something I do know about and am learning deeper. I also enjoyed the airport code jokes: IAH (Houston – i am here), IAD (Dulles – i am delayed), and ORD (Chicago – ordeal). I’m always impressed Venkat can live code in front of so many people. I’d never seen incubator code in use. Nice it gets a temporary package name; can’t use it by accident. Venkat used IntelliJ to create a module. I don’t think I’ve ever seen him use IntelliJ :). Great audience questions on structured task scope. The scoped value thing made my head swim for a bit, but I get it now.

[2022 javaone] hands on lab project loom

Facilitated by Oracle (Nicolai/Jose)

For more see the table of contents

Overview

  • The lab uses Oracle’s cloud environment. Setup was clear and well documented.
  • It’s a throwaway env only good for a few hours so you don’t have to worry about cleanup.
  • Can also do locally if prefer

Links

  • Workshop: https://bit.ly/ocw22-hol3733
  • https://github.com/JosePaumard/2022_javaone-loom-livelab.git

Virtual Threads

  • A virtual thread runs on a “real” platform thread called a carrier thread
  • Can be mounted/dismounted from carrier thread when blocks
  • It’s cool seeing a platform thread run so many virtual threads

Structured Concurrency

  • I just skimmed this part (had ice cream and got distracted talking to people so didn’t do the code for this half.) Conveniently, it is in github and I can do it in the future. Probably when it makes it out of incubator so I don’t forget everything.

My take

It took almost half an hour to get started. The online editor doesn’t work in Mac Safari so did the setup twice. I could have used Java 19 locally, but wanted to see what the lab environment looked like. I had enough time though so it was ok.’

I got to use single file source code execution (the lab didn’t say to, but less typing.) Must tease someone about its usefulness. And I got to to try out Loom.