Atomicfu is a multiplatform Kotlin compiler plugin and library for atomic operations across JVM, Native, JS, and Wasm platforms
—
Reentrant locks and lock-free synchronization primitives for thread-safe coordination without blocking. This API provides alternatives to traditional blocking synchronization mechanisms.
Creates reentrant lock instances for thread-safe coordination.
/**
* Creates a reentrant lock for thread-safe coordination
* @returns ReentrantLock instance for lock-based synchronization
*/
fun reentrantLock(): ReentrantLockUsage Examples:
import kotlinx.atomicfu.locks.*
// Create a reentrant lock
val lock = reentrantLock()Thread-safe lock implementation with support for reentrant locking.
/**
* Reentrant lock for thread-safe coordination
*/
class ReentrantLock {
/** Acquires the lock, blocking if necessary */
fun lock(): Unit
/** Releases the lock */
fun unlock(): Unit
/** Attempts to acquire the lock without blocking */
fun tryLock(): Boolean
/** Executes action while holding the lock */
inline fun <T> withLock(action: () -> T): T
}Usage Examples:
import kotlinx.atomicfu.locks.*
class ThreadSafeCounter {
private val lock = reentrantLock()
private var count = 0
fun increment(): Int {
return lock.withLock {
++count
}
}
fun get(): Int {
return lock.withLock {
count
}
}
fun tryIncrement(): Boolean {
return if (lock.tryLock()) {
try {
count++
true
} finally {
lock.unlock()
}
} else {
false
}
}
}
// Manual lock/unlock pattern
class ManualLockExample {
private val lock = reentrantLock()
private val items = mutableListOf<String>()
fun addItem(item: String) {
lock.lock()
try {
items.add(item)
} finally {
lock.unlock()
}
}
}Common patterns for building thread-safe data structures using locks.
Usage Examples:
// Pattern 1: Thread-safe cache
class ThreadSafeCache<K, V> {
private val lock = reentrantLock()
private val cache = mutableMapOf<K, V>()
fun get(key: K): V? {
return lock.withLock {
cache[key]
}
}
fun put(key: K, value: V): V? {
return lock.withLock {
cache.put(key, value)
}
}
fun computeIfAbsent(key: K, factory: (K) -> V): V {
return lock.withLock {
cache.computeIfAbsent(key, factory)
}
}
}
// Pattern 2: Producer-consumer queue
class ThreadSafeQueue<T> {
private val lock = reentrantLock()
private val queue = ArrayDeque<T>()
fun offer(item: T) {
lock.withLock {
queue.offer(item)
}
}
fun poll(): T? {
return lock.withLock {
queue.poll()
}
}
fun size(): Int {
return lock.withLock {
queue.size
}
}
}
// Pattern 3: Lazy initialization
class ThreadSafeLazy<T>(private val initializer: () -> T) {
private val lock = reentrantLock()
private var value: T? = null
private var initialized = false
fun get(): T {
if (initialized) {
@Suppress("UNCHECKED_CAST")
return value as T
}
return lock.withLock {
if (!initialized) {
value = initializer()
initialized = true
}
@Suppress("UNCHECKED_CAST")
value as T
}
}
}
// Pattern 4: Multiple readers, single writer
class ReadWriteExample {
private val lock = reentrantLock()
private var data = ""
fun read(): String {
return lock.withLock {
data
}
}
fun write(newData: String) {
lock.withLock {
data = newData
}
}
fun update(transform: (String) -> String) {
lock.withLock {
data = transform(data)
}
}
}When using locks in atomicfu:
withLock for exception safety: Always prefer withLock {} over manual lock()/unlock() pairstryLock() properly: Always check the return value and handle both success and failure casesExample of proper exception handling:
class SafeLockUsage {
private val lock = reentrantLock()
private val resources = mutableListOf<String>()
// Preferred: withLock handles exceptions automatically
fun safeAdd(item: String) {
lock.withLock {
resources.add(item)
// Exception here is handled properly
}
}
// Manual lock/unlock with proper exception handling
fun manualAdd(item: String) {
lock.lock()
try {
resources.add(item)
} finally {
lock.unlock() // Always called, even if exception occurs
}
}
// tryLock pattern
fun conditionalAdd(item: String): Boolean {
return if (lock.tryLock()) {
try {
resources.add(item)
true
} finally {
lock.unlock()
}
} else {
false // Could not acquire lock
}
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-jetbrains-kotlin--kotlin-atomicfu-compiler-plugin