🏷 Concurrency
11 patterns
Topic: Concurrency
All Java patterns related to Concurrency — java.evolved
Streams
Virtual thread executor
Old
ExecutorService exec =
Executors.newFixedThreadPool(10);
try {
futures = tasks.stream()
.map(t -> exec.submit(t))
.toList();
} finally {
exec.shutdown();
}
Modern
try (var exec = Executors
.newVirtualThreadPerTaskExecutor()) {
var futures = tasks.stream()
.map(exec::submit)
.toList();
}
hover to see modern →
JDK 21+
learn more →
Concurrency
CompletableFuture chaining
Old
Future<String> future =
executor.submit(this::fetchData);
String data = future.get(); // blocks
String result = transform(data);
Modern
CompletableFuture.supplyAsync(
this::fetchData
)
.thenApply(this::transform)
.thenAccept(IO::println);
hover to see modern →
JDK 8+
learn more →
Concurrency
Concurrent HTTP with virtual threads
Old
ExecutorService pool =
Executors.newFixedThreadPool(10);
List<Future<String>> futures =
urls.stream()
.map(u -> pool.submit(
() -> fetchUrl(u)))
.toList();
// manual shutdown, blocking get()
Modern
try (var exec = Executors
.newVirtualThreadPerTaskExecutor()) {
var results = urls.stream()
.map(u -> exec.submit(
() -> client.send(req(u),
ofString()).body()))
.toList().stream()
.map(Future::join).toList();
}
hover to see modern →
JDK 21+
learn more →
Concurrency
ExecutorService auto-close
Old
ExecutorService exec =
Executors.newCachedThreadPool();
try {
exec.submit(task);
} finally {
exec.shutdown();
exec.awaitTermination(
1, TimeUnit.MINUTES);
}
Modern
try (var exec =
Executors.newCachedThreadPool()) {
exec.submit(task);
}
// auto shutdown + await on close
hover to see modern →
JDK 19+
learn more →
Concurrency
Lock-free lazy initialization
Old
class Config {
private static volatile Config inst;
static Config get() {
if (inst == null) {
synchronized (Config.class) {
if (inst == null)
inst = load();
}
}
return inst;
}
}
Modern
class Config {
private static final
StableValue<Config> INST =
StableValue.of(Config::load);
static Config get() {
return INST.get();
}
}
hover to see modern →
JDK 25+
learn more →
Concurrency
Modern Process API
Old
Process p = Runtime.getRuntime()
.exec("ls -la");
int code = p.waitFor();
// no way to get PID
// no easy process info
Modern
ProcessHandle ph =
ProcessHandle.current();
long pid = ph.pid();
ph.info().command()
.ifPresent(IO::println);
ph.children().forEach(
c -> IO.println(c.pid()));
hover to see modern →
JDK 9+
learn more →
Concurrency
Scoped values
Old
static final ThreadLocal<User> CURRENT =
new ThreadLocal<>();
void handle(Request req) {
CURRENT.set(authenticate(req));
try { process(); }
finally { CURRENT.remove(); }
}
Modern
static final ScopedValue<User> CURRENT =
ScopedValue.newInstance();
void handle(Request req) {
ScopedValue.where(CURRENT,
authenticate(req)
).run(this::process);
}
hover to see modern →
JDK 25+
learn more →
Concurrency
Stable values
Old
private volatile Logger logger;
Logger getLogger() {
if (logger == null) {
synchronized (this) {
if (logger == null)
logger = createLogger();
}
}
return logger;
}
Modern
private final StableValue<Logger> logger =
StableValue.of(this::createLogger);
Logger getLogger() {
return logger.get();
}
hover to see modern →
JDK 25+
learn more →
Concurrency
Structured concurrency
Old
ExecutorService exec =
Executors.newFixedThreadPool(2);
Future<User> u = exec.submit(this::fetchUser);
Future<Order> o = exec.submit(this::fetchOrder);
try {
return combine(u.get(), o.get());
} finally { exec.shutdown(); }
Modern
try (var scope = new StructuredTaskScope
.ShutdownOnFailure()) {
var u = scope.fork(this::fetchUser);
var o = scope.fork(this::fetchOrder);
scope.join().throwIfFailed();
return combine(u.get(), o.get());
}
hover to see modern →
JDK 25+
learn more →
Concurrency
Thread.sleep with Duration
Old
// What unit is 5000? ms? us?
Thread.sleep(5000);
// 2.5 seconds: math required
Thread.sleep(2500);
Modern
Thread.sleep(
Duration.ofSeconds(5)
);
Thread.sleep(
Duration.ofMillis(2500)
);
hover to see modern →
JDK 19+
learn more →
Concurrency
Virtual threads
Old
Thread thread = new Thread(() -> {
System.out.println("hello");
});
thread.start();
thread.join();
Modern
Thread.startVirtualThread(() -> {
IO.println("hello");
}).join();
hover to see modern →
JDK 21+
learn more →