🧩 Structured concurrency built on JDK 21 Virtual Threads — without the magic.
ABCoroutines is a minimal, composable toolkit for running structured, cancellable tasks on JDK 21+ Virtual Threads from Kotlin.
It offers predictable lifecycle management, coroutine-style helpers, and well-tested patterns for timeouts, retries, races, and channels — all while remaining 100% compatible with kotlinx.coroutines
.
💡 Looking for cross-platform concurrency patterns? Check out ABConcurrency — the multiplatform successor bringing these coordination patterns to JVM, JS, and Native.
ABCoroutines makes it easy to use Virtual Threads as structured coroutine dispatchers.
It provides:
- A VirtualThreads
CoroutineDispatcher
backed byExecutors.newVirtualThreadPerTaskExecutor()
- A long-lived applicationScope for launching jobs
- Lifecycle management (
ensureRunning
,shutdown
,reset
) - Blocking entry point
runBlockingVT
— ideal formain
- High-level coordination patterns:
parallel
,race
,retry
,zip
— intuitive primitives for concurrent thinking - Rich timeout, retry, and channel/flow utilities
- Java interop via
ABCoroutinesInterop
(exposingExecutor
/ExecutorService
) - Over 160+ tests verifying lifecycle, cancellation, resource safety, and concurrency
Think in patterns, not primitives. Instead of wrestling with low-level concurrency:
// Express intent clearly
val userData = parallel(
{ fetchProfile() },
{ fetchPreferences() },
{ fetchNotifications() }
)
// Race multiple strategies
val data = raceForSuccess(
{ getFromCache() },
{ getFromDatabase() },
{ getFromAPI() }
)
// Handle failures gracefully
val result = retry(maxAttempts = 3, initialDelay = 100.milliseconds) {
unstableOperation()
}
ABCoroutines makes concurrent coordination as natural as sequential programming.
Module | Purpose |
---|---|
ABCoroutines.kt |
Core VT dispatcher lifecycle, scopes, and helpers |
AbcApi.kt |
Idiomatic façade exposing high-value VT utilities |
CoroutinePatterns.kt |
Common structured patterns (timeouts, retries, races, channels, flows) |
ABCoroutinesInterop.kt |
Java-facing executors (Executor , ExecutorService ) |
src/test/kotlin/... |
Comprehensive test suite covering utilities, channels, racing, load, and interop |
repositories {
mavenCentral()
}
dependencies {
implementation("tech.robd:abcoroutines:")
}
Requires JDK 21+.
import tech.robd.abcoroutines.ABCoroutines
fun main() {
ABCoroutines.runBlockingVT {
val job = launchVT {
println("Hello from a Virtual Thread: ${Thread.currentThread().isVirtual()}")
}
job.join()
}
}
val results = AbcApi.parallelVT(
{ fetchUser() },
{ fetchSettings() },
{ fetchPermissions() }
)
println(results)
val combined = AbcApi.zipVT(
{ loadConfig() },
{ fetchRemoteDefaults() }
) { config, defaults ->
config.merge(defaults)
}
val result = AbcApi.raceForSuccess(
ABCoroutines.asyncVT { callFastBackup() },
ABCoroutines.asyncVT { callSlowPrimary() }
)
println("Winner: $result")
val data = retry(
maxAttempts = 3,
initialDelay = 100.milliseconds
) {
fetchFromNetwork()
}
val response = cancelIfExceedsOrElse(500.milliseconds, fallback = { "timeout" }) {
slowApiCall()
}
val results = urls.mapConcurrent(concurrency = 5) { url ->
fetchPage(url)
}
val results = flowOf(1, 2, 3, 4, 5)
.parallelMap(concurrency = 2) { process(it) }
.toList()
import tech.robd.abcoroutines.interop.ABCoroutinesInterop;
import java.util.concurrent.CompletableFuture;
public class Example {
public static void main(String[] args) throws Exception {
var exec = ABCoroutinesInterop.virtualThreadExecutor();
var future = CompletableFuture.supplyAsync(() -> {
System.out.println(Thread.currentThread().isVirtual());
return "done";
}, exec);
System.out.println(future.get());
}
}
ABCoroutines includes a full JUnit 5 suite covering:
- ✅ Lifecycle control — shutdown, reset, ensureRunning
- ✅ Cancellation propagation
- ✅ Timeouts, retries, and race patterns
- ✅ Parallel & bounded concurrency
- ✅ Channel/Flow utilities
- ✅ Interop executors
- ✅ Load and resource cleanup
Example:
./gradlew test
Key test classes:
ABCoroutinesCancellationTests
ConcurrencyAndRacingTests
IntegrationAndLoadTests
ChannelAndFlowTests
CoreRawExecutorInteropTests
ABCoroutines is intentionally small, explicit, and unmagical:
- No hidden thread pools — just Virtual Threads
- No global mutable context — scopes are explicit
- Predictable shutdown and reset
- Interop with existing kotlinx.coroutines APIs
- Coordination patterns as primitives — think in terms of
parallel
,race
,retry
rather than threads and locks - Focused, readable helpers instead of frameworks
If you know coroutines, you can use ABCoroutines immediately.
- Core Virtual Thread dispatcher and lifecycle
- Comprehensive concurrency patterns
- Java interop layer
- abcoroutines-jcoroutines-interop — Advanced interop for testing and porting Java JCoroutines code to Kotlin, avoiding lock-in
- ABConcurrency — Cross-platform coordination patterns (JVM, JS, Native)
- IDE integration with pattern detection
- Educational materials and tutorials
- JCoroutines — Structured concurrency for pure Java 21
- ABCoroutines-JCoroutinesInterop (Coming Soon) — Demonstrates Java ⇆ Kotlin structured concurrency bridge
- ABConcurrency (Coming Soon) — Cross-platform concurrency patterns for Kotlin Multiplatform
Copyright 2025 Rob Deas
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy at
http://www.apache.org/licenses/LICENSE-2.0
- Version: 0.1.0
- License: Apache 2.0
- Build: Gradle Kotlin DSL
- Tested: JDK 21
🧩 ABCoroutines: Structured concurrency for Virtual Threads — lightweight, explicit, and ready for real workloads.