AtomicFU allows you to declare atomic variables and perform lock-free operations using idiomatic Kotlin syntax.
Declaration
Use atomic(initialValue) to declare an atomic variable. For integers and longs, type inference works automatically:
import kotlinx.atomicfu.*
private val top = atomic<Node?>(null) // Atomic reference
val myInt = atomic(0) // Atomic integer
val myLong = atomic(0L) // Atomic long
Volatile Reads and Writes
Use the .value property for volatile access:
fun isEmpty() = top.value == null // volatile read
fun clear() { top.value = null } // volatile write
Atomic Updates
For lock-free logic, use compareAndSet or higher-level extension functions like update, updateAndGet, and getAndUpdate:
// Direct CAS
if (top.compareAndSet(expect, update)) { ... }
// Idiomatic updates
fun push(v: Value) = top.update { cur -> Node(v, cur) }
fun pop(): Value? = top.getAndUpdate { cur -> cur?.next }?.value
// Looping primitive
top.loop { cur ->
// while(true) loop that volatile-reads current value
}
Integer/Long Operations
Atomic integers and longs support standard operations like getAndIncrement(), incrementAndGet(), getAndAdd(), etc., as well as += and -= operators.
import kotlinx.atomicfu.*
private val top = atomic<Node?>(null)
fun isEmpty() = top.value == null
fun clear() { top.value = null }
if (top.compareAndSet(expect, update)) { /* ... */ }
top.loop { cur ->
// while(true) loop that volatile-reads current value
}
fun push(v: Value) = top.update { cur -> Node(v, cur) }
fun pop(): Value? = top.getAndUpdate { cur -> cur?.next }?.value
val myInt = atomic(0)
val myLong = atomic(0L)