# \`Threads.atomic\_cas!\`, \`Threads.SpinLock\`, and \`@atomic\` documentation

**URL:** https://discourse.julialang.org/t/threads-atomic-cas-threads-spinlock-and-atomic-documentation/134369
**Category:** General Usage
**Tags:** documentation, multithreading, atomic
**Created:** [December 5, 2025, 9:29am UTC](https://discourse.julialang.org/t/threads-atomic-cas-threads-spinlock-and-atomic-documentation/134369 "2025-12-05T09:29:07Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![Marco\_Lombardi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_lombardi/32/14608_2.png) [@Marco\_Lombardi](https://discourse.julialang.org/u/Marco_Lombardi)
#### Post date: [December 5, 2025, 9:29am UTC](https://discourse.julialang.org/t/threads-atomic-cas-threads-spinlock-and-atomic-documentation/134369/1 "2025-12-05T09:29:07Z")

</div>

Reading the Julia manual, I see that there is a “mild” deprecation for a series of atomic-related functions, including `Threads.atomic_cas!`. I understand this is in favor of the `@atomic` macro, which is apparently more granular. However, at least from a user perspective, this opens a number of issues:

- All `@atomic` operations I have seen do not seem to reproduce the behavior of `Threads.atomic_cas!`, so I am left with the doubt if there is way to replace this function;

- The `order` symbol in the `@atomic` macro is very poorly documented. The manual refers to the [Julia Atomics Manifesto](https://gist.github.com/vtjnash/11b0031f2e2a66c9c24d33e810b34ec0), which however does not describe the `order`, but points to yet [another document](https://doc.rust-lang.org/std/sync/atomic/struct.AtomicI8.html) which however is for Rust. From a user perspective this is really confusing (especially if one is not fluent in Rust…).

- I wanted to use `Threads.atomic_cas!` to implement a sort of _soft lock_. Essentially, concurrent threads would check if a shared resource (a block of memory) is free. If it is, they would use it (with a lock); if not, they would perform a slower calculation re-allocating locally the same resource. To check how this is implemented in the Julia code, I browsed the `trylock(::Threads.SpinLock)` method, and saw this:

Thank you

---

<div class="post-metadata">

### Author: ![foobar\_lv2](https://avatars.discourse-cdn.com/v4/letter/f/ee59a6/32.png) [@foobar\_lv2](https://discourse.julialang.org/u/foobar_lv2)
#### Post date: [December 5, 2025, 10:59am UTC](https://discourse.julialang.org/t/threads-atomic-cas-threads-spinlock-and-atomic-documentation/134369/2 "2025-12-05T10:59:10Z")

</div>

This is mostly equivalent to whatever scheme you would implement with `Threads.atomic_cas!`. Julia spinlocks also carry the following properties:

1. If any lock is held, then finalizers are disabled.
2. If no lock is held, then finalizers are enabled again.
3. You are not permitted to acquire a lock and then release it on a different task.

In order to get the finalizer thingy working, trylock has to disable finalizers before acquiring the lock; and, if it has disabled finalizers and then fails to acquire the lock, it has to enable them again.

Since disabling and enabling finalizers is not free, trylock uses double-checked locking.

In other words: Yes, it can happen that someone else snatches the lock after the `if l.owned == 0` and before `p = @atomicswap :acquire l.owned = 1`. In that case, `p == 1` and we will re-enable finalizers and return false, i.e. fail to acquire the lock. The worst case for this race condition is that we have wasted some cycles enabling and disabling finalizers.

Whether to use Base spinlock depends on whether you care about suppressing finalizers inside critical sections, and whether you might migrate the held lock between tasks.

If you don’t want to use SpinLock, the successor to `Threads.atomic_cas!` is `@atomicreplace` if you want to use sugary syntax macros, or `Base.replacefield!` / `Base.replaceproperty!` if you prefer non-macro “real” APIs.

---

<div class="post-metadata">

### Author: ![Marco\_Lombardi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marco_lombardi/32/14608_2.png) [@Marco\_Lombardi](https://discourse.julialang.org/u/Marco_Lombardi)
#### Post date: [December 5, 2025, 2:16pm UTC](https://discourse.julialang.org/t/threads-atomic-cas-threads-spinlock-and-atomic-documentation/134369/3 "2025-12-05T14:16:55Z")

</div>

Thank you so much for your detailed and clear explanations @foobar_lv2 !
