[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.

Happy Book Birthday! OCP 17 Practice Tests

Our Java 17 Practice Tests book has been released! This is a major rewrite of our Java OCP 11 book with hundreds of new and revised questions! If you already have our Java 17 Study Guide, you can purchase it individually, or you can buy it as kit.

The Practice Tests OCP 17 book contains 11 chapters helping you review and reinforce each objective. It also includes 3 full practice exams. All questions in the practice test book are unique from those in the complete study guide.

sealed classes, records and enums

Sometimes we write something for the book, only to realize it shouldn’t be in the book. This post is an example. Do you think this legal?

public sealed interface MySealedClass permits MyRecord, MyEnum {
}

record MyRecord() implements MySealedClass {}

enum MyEnum implements MySealedClass { VALUE }

It is! A sealed interface can be implemented by any Java type. Which means records and enums are included.