{"id":29627236,"url":"https://github.com/Kotlin/kotlinx.atomicfu","last_synced_at":"2025-07-21T08:01:43.319Z","repository":{"id":39380241,"uuid":"99576820","full_name":"Kotlin/kotlinx-atomicfu","owner":"Kotlin","description":"The idiomatic way to use atomic operations in Kotlin","archived":false,"fork":false,"pushed_at":"2025-07-15T20:31:38.000Z","size":1895,"stargazers_count":1015,"open_issues_count":55,"forks_count":67,"subscribers_count":30,"default_branch":"master","last_synced_at":"2025-07-16T18:41:10.062Z","etag":null,"topics":["atomic","kotlin","kotlinx"],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Kotlin.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGES.md","contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2017-08-07T12:41:58.000Z","updated_at":"2025-07-14T06:38:22.000Z","dependencies_parsed_at":"2023-02-10T15:01:32.736Z","dependency_job_id":"fa6d3a3c-fed2-4c9e-a4bb-8c4c86ee72be","html_url":"https://github.com/Kotlin/kotlinx-atomicfu","commit_stats":null,"previous_names":["kotlin/kotlinx.atomicfu"],"tags_count":81,"template":false,"template_full_name":null,"purl":"pkg:github/Kotlin/kotlinx-atomicfu","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kotlin%2Fkotlinx-atomicfu","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kotlin%2Fkotlinx-atomicfu/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kotlin%2Fkotlinx-atomicfu/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kotlin%2Fkotlinx-atomicfu/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Kotlin","download_url":"https://codeload.github.com/Kotlin/kotlinx-atomicfu/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Kotlin%2Fkotlinx-atomicfu/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":266263057,"owners_count":23901353,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["atomic","kotlin","kotlinx"],"created_at":"2025-07-21T08:01:14.504Z","updated_at":"2025-07-21T08:01:43.312Z","avatar_url":"https://github.com/Kotlin.png","language":"Kotlin","funding_links":[],"categories":["Libraries"],"sub_categories":["➿ Asynchronous","Utility"],"readme":"# AtomicFU \n\n[![Kotlin Beta](https://kotl.in/badges/beta.svg)](https://kotlinlang.org/docs/components-stability.html)\n[![JetBrains official project](https://jb.gg/badges/official.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)\n[![GitHub license](https://img.shields.io/badge/license-Apache%20License%202.0-blue.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0)\n[![Maven Central](https://img.shields.io/maven-central/v/org.jetbrains.kotlinx/atomicfu)](https://search.maven.org/artifact/org.jetbrains.kotlinx/atomicfu/0.29.0/pom)\n[![Kotlin](https://img.shields.io/badge/kotlin-2.2-blue.svg?logo=kotlin)](http://kotlinlang.org)\n\n\u003eNote on Beta status: the plugin is in its active development phase and changes from release to release.\n\u003eWe do provide a compatibility of atomicfu-transformed artifacts between releases, but we do not provide \n\u003estrict compatibility guarantees on plugin API and its general stability between Kotlin versions.\n\n**Atomicfu** is a multiplatform library that provides the idiomatic and efficient way of using atomic operations in Kotlin.\n\n## Table of contents\n- [Requirements](#requirements)\n- [Features](#features)\n- [Example](#example)\n- [Quickstart](#quickstart)\n  - [Apply plugin to a project](#apply-plugin)\n    - [Gradle configuration](#gradle-configuration)\n    - [Maven configuration](#maven-configuration)\n- [Usage constraints](#usage-constraints)  \n- [Transformation modes](#transformation-modes)\n  - [Atomicfu compiler plugin](#atomicfu-compiler-plugin)\n- [Options for post-compilation transformation](#options-for-post-compilation-transformation) \n  - [JVM options](#jvm-options)\n  - [JS options](#js-options)\n- [More features](#more-features)\n  - [Arrays of atomic values](#arrays-of-atomic-values)\n  - [User-defined extensions on atomics](#user-defined-extensions-on-atomics)\n  - [Locks](#locks)\n  - [Tracing operations](#tracing-operations)\n- [Kotlin/Native support](#kotlin-native-support)\n\n## Requirements\n\nTo apply the current version of the atomicfu Gradle plugin, your project has to use:\n\n* Gradle `8.2` or newer\n\n* Kotlin `2.2.0` or newer\n\nConsider using [previous versions](https://github.com/Kotlin/kotlinx-atomicfu/releases) of the plugin\nif your project could not meet these requirements.\n\n\u003e **Note on Kotlin version:** Currently, the `kotlinx-atomicfu` Gradle plugin only relies on the version of Kotlin Gradle Plugin (KGP) present in the user's project.\n\u003e It's important to note this constraint if your project configures the custom Kotlin compiler version or modifies the Kotlin Native compiler version using `kotlin.native.version` property.\n\n## Features\n\n* Complete multiplatform support: JVM, Native, JS and Wasm (since Kotlin 1.9.20).\n* Code it like a boxed value `atomic(0)`, but run it in production efficiently:\n  * For **JVM**: an atomic value is represented as a plain value atomically updated with `java.util.concurrent.atomic.AtomicXxxFieldUpdater` from the Java standard library.\n  * For **JS**: an atomic value is represented as a plain value.\n  * For **Native**: atomic operations are delegated to Kotlin/Native atomic intrinsics.\n  * For **Wasm**: an atomic value is not transformed, it remains boxed, and `kotlinx-atomicfu` library is used as a runtime dependency.\n* Use Kotlin-specific extensions (e.g. inline `loop`, `update`, `updateAndGet` functions).\n* Use atomic arrays, user-defined extensions on atomics and locks (see [more features](#more-features)).\n* [Tracing operations](#tracing-operations) for debugging.\n  \n## Example\n\nLet us declare a `top` variable for a lock-free stack implementation:\n\n```kotlin\nimport kotlinx.atomicfu.* // import top-level functions from kotlinx.atomicfu\n\nprivate val top = atomic\u003cNode?\u003e(null) \n```\n\nUse `top.value` to perform volatile reads and writes:\n\n```kotlin\nfun isEmpty() = top.value == null  // volatile read\nfun clear() { top.value = null }   // volatile write\n``` \n\nUse `compareAndSet` function directly:\n\n```kotlin\nif (top.compareAndSet(expect, update)) ... \n```\n\nUse higher-level looping primitives (inline extensions), for example:\n\n```kotlin\ntop.loop { cur -\u003e   // while(true) loop that volatile-reads current value \n   ...\n}\n```\n\nUse high-level `update`, `updateAndGet`, and `getAndUpdate`, \nwhen possible, for idiomatic lock-free code, for example:\n\n```kotlin\nfun push(v: Value) = top.update { cur -\u003e Node(v, cur) }\nfun pop(): Value? = top.getAndUpdate { cur -\u003e cur?.next } ?.value\n```\n\nDeclare atomic integers and longs using type inference:\n\n```kotlin\nval myInt = atomic(0)    // note: integer initial value\nval myLong = atomic(0L)  // note: long initial value   \n```\n\nInteger and long atomics provide all the usual `getAndIncrement`, `incrementAndGet`, `getAndAdd`, `addAndGet`, and etc\noperations. They can be also atomically modified via `+=` and `-=` operators.\n\n## Quickstart\n### Apply plugin\n#### Gradle configuration\n\n\u003e **New plugin id:** Please pay attention, that starting from version `0.25.0` the plugin id is `org.jetbrains.kotlinx.atomicfu`\n\nAdd the following to your top-level build file:\n\n\u003cdetails open\u003e\n\u003csummary\u003eKotlin\u003c/summary\u003e\n\n```kotlin\nplugins {\n     id(\"org.jetbrains.kotlinx.atomicfu\") version \"0.29.0\"\n}\n```\n\u003c/details\u003e\n\n\u003cdetails open\u003e\n\u003csummary\u003eGroovy\u003c/summary\u003e\n\n```groovy\nplugins {\n    id 'org.jetbrains.kotlinx.atomicfu' version '0.29.0'\n}\n```\n\u003c/details\u003e\n\n\n#### Legacy plugin application\n\n\u003cdetails open\u003e\n\u003csummary\u003eKotlin\u003c/summary\u003e\n\n```kotlin\nbuildscript {\n  repositories {\n    mavenCentral()\n  }\n\n  dependencies {\n    classpath(\"org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.29.0\")\n  }\n}\n\napply(plugin = \"org.jetbrains.kotlinx.atomicfu\")\n```\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eGroovy\u003c/summary\u003e\n\n```groovy\nbuildscript {\n    repositories {\n        mavenCentral()\n    }\n    dependencies {\n        classpath 'org.jetbrains.kotlinx:atomicfu-gradle-plugin:0.29.0'\n    }\n}\n  \napply plugin: 'org.jetbrains.kotlinx.atomicfu'\n```\n\u003c/details\u003e\n\n#### Maven configuration\n\nMaven configuration is supported for JVM projects.\n\n\n\u003cdetails open\u003e\n\u003csummary\u003eDeclare atomicfu version\u003c/summary\u003e\n\n```xml\n\u003cproperties\u003e\n     \u003catomicfu.version\u003e0.29.0\u003c/atomicfu.version\u003e\n\u003c/properties\u003e \n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003eDeclare provided dependency on the AtomicFU library\u003c/summary\u003e\n\n```xml\n\u003cdependencies\u003e\n    \u003cdependency\u003e\n        \u003cgroupId\u003eorg.jetbrains.kotlinx\u003c/groupId\u003e\n        \u003cartifactId\u003eatomicfu\u003c/artifactId\u003e\n        \u003cversion\u003e${atomicfu.version}\u003c/version\u003e\n        \u003cscope\u003eprovided\u003c/scope\u003e\n    \u003c/dependency\u003e\n\u003c/dependencies\u003e\n```\n\n\u003c/details\u003e\n\nConfigure build steps so that Kotlin compiler puts classes into a different `classes-pre-atomicfu` directory,\nwhich is then transformed to a regular `classes` directory to be used later by tests and delivery.\n\n\u003cdetails\u003e\n\u003csummary\u003eBuild steps\u003c/summary\u003e\n\n```xml\n\u003cbuild\u003e\n  \u003cplugins\u003e\n    \u003c!-- compile Kotlin files to staging directory --\u003e\n    \u003cplugin\u003e\n      \u003cgroupId\u003eorg.jetbrains.kotlin\u003c/groupId\u003e\n      \u003cartifactId\u003ekotlin-maven-plugin\u003c/artifactId\u003e\n      \u003cversion\u003e${kotlin.version}\u003c/version\u003e\n      \u003cexecutions\u003e\n        \u003cexecution\u003e\n          \u003cid\u003ecompile\u003c/id\u003e\n          \u003cphase\u003ecompile\u003c/phase\u003e\n          \u003cgoals\u003e\n            \u003cgoal\u003ecompile\u003c/goal\u003e\n          \u003c/goals\u003e\n          \u003cconfiguration\u003e\n            \u003coutput\u003e${project.build.directory}/classes-pre-atomicfu\u003c/output\u003e\n          \u003c/configuration\u003e\n        \u003c/execution\u003e\n      \u003c/executions\u003e\n    \u003c/plugin\u003e\n    \u003c!-- transform classes with AtomicFU plugin --\u003e\n    \u003cplugin\u003e\n      \u003cgroupId\u003eorg.jetbrains.kotlinx\u003c/groupId\u003e\n      \u003cartifactId\u003eatomicfu-maven-plugin\u003c/artifactId\u003e\n      \u003cversion\u003e${atomicfu.version}\u003c/version\u003e\n      \u003cexecutions\u003e\n        \u003cexecution\u003e\n          \u003cgoals\u003e\n            \u003cgoal\u003etransform\u003c/goal\u003e\n          \u003c/goals\u003e\n          \u003cconfiguration\u003e\n            \u003cinput\u003e${project.build.directory}/classes-pre-atomicfu\u003c/input\u003e\n            \u003c!-- \"VH\" to use Java 9 VarHandle, \"BOTH\" to produce multi-version code --\u003e\n            \u003cvariant\u003eFU\u003c/variant\u003e\n          \u003c/configuration\u003e\n        \u003c/execution\u003e\n      \u003c/executions\u003e\n    \u003c/plugin\u003e\n  \u003c/plugins\u003e\n\u003c/build\u003e\n```\n\n\u003c/details\u003e\n\n## Usage constraints\n\n* Declare atomic variables as `private val` or `internal val`. You can use just (public) `val`, \n  but make sure they are not directly accessed outside of your Kotlin module (outside of the source set).\n  Access to the atomic variable itself shall be encapsulated.\n* To expose the value of an atomic property to the public, use a delegated property declared in the same scope\n  (see [atomic delegates](#atomic-delegates) section for details):\n\n```kotlin\nprivate val _foo = atomic\u003cT\u003e(initial) // private atomic, convention is to name it with leading underscore\npublic var foo: T by _foo            // public delegated property (val/var)\n```\n* Only simple operations on atomic variables _directly_ are supported. \n  * Do not read references on atomic variables into local variables,\n    e.g. `top.compareAndSet(...)` is ok, while `val tmp = top; tmp...` is not. \n  * Do not leak references on atomic variables in other way (return, pass as params, etc). \n* Do not introduce complex data flow in parameters to atomic variable operations, \n  i.e. `top.value = complex_expression` and `top.compareAndSet(cur, complex_expression)` are not supported \n  (more specifically, `complex_expression` should not have branches in its compiled representation).\n  Extract `complex_expression` into a variable when needed.\n\n## Atomicfu compiler plugin\n\nTo provide a user-friendly atomic API on the frontend and efficient usage of atomic values on the backend kotlinx-atomicfu library uses the compiler plugin to transform \nIR for all the target backends: \n* **JVM**: atomics are replaced with `java.util.concurrent.atomic.AtomicXxxFieldUpdater`.\n* **Native**: atomics are implemented via atomic intrinsics on Kotlin/Native.\n* **JS**: atomics are unboxed and represented as plain values.\n\nTo turn on IR transformations set the following properties in your `gradle.properties` file:\n\n\u003e Please note, that starting from version `0.24.0` of the library your project is required to use `Kotlin version \u003e= 1.9.0`. \n\u003e See the [requirements section](#Requirements).\n\n```groovy\nkotlinx.atomicfu.enableJvmIrTransformation=true // for JVM IR transformation\nkotlinx.atomicfu.enableNativeIrTransformation=true // for Native IR transformation\nkotlinx.atomicfu.enableJsIrTransformation=true // for JS IR transformation\n```\n\n\u003cdetails open\u003e\n\u003csummary\u003e Here are the configuration properties in case you use older versions of the library lower than 0.24.0. \u003c/summary\u003e\n\nFor `Kotlin \u003e= 1.7.20`\n\n```groovy\nkotlinx.atomicfu.enableJvmIrTransformation=true // for JVM IR transformation\nkotlinx.atomicfu.enableNativeIrTransformation=true // for Native IR transformation\nkotlinx.atomicfu.enableJsIrTransformation=true // for JS IR transformation\n```\n\nFor `Kotlin \u003e= 1.6.20` and `Kotlin \u003c 1.7.20`\n\n```groovy\nkotlinx.atomicfu.enableIrTransformation=true // only JS IR transformation is supported\n```\n\nAlso for JS backend make sure that `ir` or `both` compiler mode is set:\n\n```groovy\nkotlin.js.compiler=ir // or both\n```\n\n\u003c/details\u003e\n\n\n## Options for post-compilation transformation\n\nSome configuration options are available for _post-compilation transform tasks_ on JVM and JS.\n\nTo set configuration options you should create `atomicfu` section in a `build.gradle` file, \nlike this:\n```groovy\natomicfu {\n  dependenciesVersion = '0.29.0'\n}\n```\n\n### JVM options\n\nTo turn off transformation for Kotlin/JVM set option `transformJvm` to `false`.\n\nConfiguration option `jvmVariant` defines the Java class that replaces atomics during bytecode transformation.\nHere are the valid options:\n- `FU` – atomics are replaced with [AtomicXxxFieldUpdater](https://docs.oracle.com/javase/10/docs/api/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.html).\n- `VH` – atomics are replaced with [VarHandle](https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/VarHandle.html), \n  this option is supported for JDK 9+.\n- `BOTH` – [multi-release jar file](https://openjdk.java.net/jeps/238) will be created with both `AtomicXxxFieldUpdater` for JDK \u003c= 8 and `VarHandle` for JDK 9+.\n\n### JS options\n\n\u003e Starting from version `0.26.0` `transformJs` flag does not take any effect and is disabled by default. \n\u003e Please ensure that this flag is not used in the atomicfu configuration of your project, you can safely remove it.\n\nHere are all available configuration options (with their defaults):\n```groovy\natomicfu {\n  dependenciesVersion = '0.29.0' // set to null to turn-off auto dependencies\n  transformJvm = true // set to false to turn off JVM transformation\n  jvmVariant = \"FU\" // JVM transformation variant: FU,VH, or BOTH\n}\n```\n\n## More features\n\nAtomicFU provides some additional features that you can use.\n\n### Arrays of atomic values\n\nYou can declare arrays of all supported atomic value types. \nBy default arrays are transformed into the corresponding `java.util.concurrent.atomic.Atomic*Array` instances.\n\nIf you configure `variant = \"VH\"` an array will be transformed to plain array using \n[VarHandle](https://docs.oracle.com/javase/9/docs/api/java/lang/invoke/VarHandle.html) to support atomic operations.\n  \n```kotlin\nval a = atomicArrayOfNulls\u003cT\u003e(size) // similar to Array constructor\n\nval x = a[i].value // read value\na[i].value = x // set value\na[i].compareAndSet(expect, update) // do atomic operations\n```\n\n### Atomic delegates\n\nYou can expose the value of an atomic property to the public, using a delegated property \ndeclared in the same scope:\n\n```kotlin\nprivate val _foo = atomic\u003cT\u003e(initial) // private atomic, convention is to name it with leading underscore\npublic var foo: T by _foo            // public delegated property (val/var)\n```\n\nYou can also delegate a property to the atomic factory invocation, that is equal to declaring a volatile property:  \n\n```kotlin\npublic var foo: T by atomic(0)\n```\n\nThis feature is only supported for the IR transformation mode, see the [atomicfu compiler plugin](#atomicfu-compiler-plugin) section for details.\n\n### User-defined extensions on atomics\n\nYou can define you own extension functions on `AtomicXxx` types but they must be `inline` and they cannot\nbe public and be used outside of the module they are defined in. For example:\n\n```kotlin\n@Suppress(\"NOTHING_TO_INLINE\")\nprivate inline fun AtomicBoolean.tryAcquire(): Boolean = compareAndSet(false, true)\n```\n\n### Locks\n\nThis project includes `kotlinx.atomicfu.locks` package providing multiplatform locking primitives that\nrequire no additional runtime dependencies on Kotlin/JVM and Kotlin/JS with a library implementation for \nKotlin/Native.\n\n* `SynchronizedObject` is designed for inheritance. You write `class MyClass : SynchronizedObject()` and then \nuse `synchronized(instance) { ... }` extension function similarly to the \n[synchronized](https://kotlinlang.org/api/latest/jvm/stdlib/kotlin/synchronized.html)\nfunction from the standard library that is available for JVM. The `SynchronizedObject` superclass gets erased\n(transformed to `Any`) on JVM and JS, with `synchronized` leaving no trace in the code on JS and getting \nreplaced with built-in monitors for locking on JVM.\n\n* `ReentrantLock` is designed for delegation. You write `val lock = reentrantLock()` to construct its instance and\nuse `lock`/`tryLock`/`unlock` functions or `lock.withLock { ... }` extension function similarly to the way\n[jucl.ReentrantLock](https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/locks/ReentrantLock.html)\nis used on JVM. On JVM it is a typealias to the later class, erased on JS.   \n\n\u003e Note that package `kotlinx.atomicfu.locks` is experimental explicitly even while atomicfu is experimental itself,\n\u003e meaning that no ABI guarantees are provided whatsoever. API from this package is not recommended to use in libraries\n\u003e that other projects depend on.\n\n### Tracing operations\n\nYou can debug your tests tracing atomic operations with a special trace object:\n\n```kotlin\nprivate val trace = Trace()\nprivate val current = atomic(0, trace)\n\nfun update(x: Int): Int {           \n    // custom trace message\n    trace { \"calling update($x)\" }\n    // automatic tracing of modification operations \n    return current.getAndAdd(x)\n}\n```      \n\nAll trace messages are stored in a cyclic array inside `trace`. \n \nYou can optionally set the size of trace's message array and format function. For example, \nyou can add a current thread name to the traced messages:\n\n```kotlin\nprivate val trace = Trace(size = 64) {   \n    index, // index of a trace message \n    text   // text passed when invoking trace { text }\n    -\u003e \"$index: [${Thread.currentThread().name}] $text\" \n} \n```                           \n\n`trace` is only seen before transformation and completely erased after on Kotlin/JVM and Kotlin/JS.\n\n## Kotlin Native support\n\nSince Kotlin/Native does not generally provide binary compatibility between versions,\nyou should use the same version of Kotlin compiler as was used to build AtomicFU.\nSee [gradle.properties](gradle.properties) in AtomicFU project for its `kotlin_version`.\n\nAvailable Kotlin/Native targets are based on non-deprecated official targets [Tier list](https://kotlinlang.org/docs/native-target-support.html)\n with the corresponding compatibility guarantees.\n\n### Gradle Build Scans\n\n[Gradle Build Scans](https://scans.gradle.com/) can provide insights into an Atomicfu Build.\nJetBrains runs a [Gradle Develocity server](https://ge.jetbrains.com/scans?search.rootProjectNames=kotlinx-atomicfu).\nthat can be used to automatically upload reports.\n\nTo automatically opt in add the following to `$GRADLE_USER_HOME/gradle.properties`.\n\n```properties\norg.jetbrains.atomicfu.build.scan.enabled=true\n# optionally provide a username that will be attached to each report\norg.jetbrains.atomicfu.build.scan.username=John Wick\n```\n\nA Build Scan may contain identifiable information. See the Terms of Use https://gradle.com/legal/terms-of-use/.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKotlin%2Fkotlinx.atomicfu","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FKotlin%2Fkotlinx.atomicfu","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FKotlin%2Fkotlinx.atomicfu/lists"}