# Mutexes and atomics

> Protect shared state with a mutex or an atomic integer cell.

Canonical: https://alice-lang.org/documentation/concurrency/synchronization/

[Documentation index](https://alice-lang.org/documentation/llms.txt) · [Complete book](https://alice-lang.org/llms-full.txt)

## Atomic counters

Use `Atomic` for a shared 64-bit integer counter or cell. Its operations are backed by .NET interlocked primitives.

```alice
counter = Atomic.new(0)
Par.For(1000) { |i| counter.add(1) }
puts counter.get
```

Expected output:

```text
1000
```

[Edit and run in the Alice playground](https://playground.alice-lang.org/#code=u.Y291bnRlciA9IEF0b21pYy5uZXcoMCkKUGFyLkZvcigxMDAwKSB7IHxpfCBjb3VudGVyLmFkZCgxKSB9CnB1dHMgY291bnRlci5nZXQ)

All additions are atomic, so the final result is 1000. A plain captured `total += 1` would be rejected in this concurrent context.

| Operation                          | Behavior                                          |
| ---------------------------------- | ------------------------------------------------- |
| `Atomic.new(value)`                | Construct a cell; default value is zero           |
| `get`                              | Atomically read                                   |
| `set(value)`                       | Atomically exchange                               |
| `add(delta)`                       | Add and return the new value                      |
| `increment`, `decrement`           | Adjust by one and return the new value            |
| `compare_and_set(expected, value)` | Replace only if equal to expected; return success |

A sequence of individually atomic operations is not one transaction. If several fields must change together, use a lock or a message-based design.

## Guard an object with Mutex

```alice
items = Mutex(List(Int32)).new(List(Int32).new)
Par.For(100) { |i| items.lock { |list| list.Add(i) } }
puts items.lock { |list| list.Count }
```

The `lock` block exposes the guarded value while the lock is held. The block can return a result. Keep the protected object inside this discipline: do not return the mutable list and then write it outside the lock.

Make critical sections short, and avoid blocking or awaiting while holding a lock. A mutex prevents simultaneous entry; it does not by itself prevent deadlocks caused by inconsistent lock ordering.

## .NET synchronization

The race checker recognizes supported `Interlocked` operations, `System.Collections.Concurrent` collections, and Alice's synchronization/message primitives. `Volatile.Write` alone is not treated as permission for arbitrary concurrent mutation. See [race safety](https://alice-lang.org/documentation/concurrency/race-safety.md) for accepted and rejected forms.

## Choose the smallest mechanism

Use an atomic for one numeric cell, a mutex for a coherent object update, a channel for transferring work, and an actor for ordered message handling. Prefer returning a computed result over sharing state when that is enough.

## Continue reading

- Previous: [Channels and actors](https://alice-lang.org/documentation/concurrency/channels.md)
- Next: [Race safety and AL0202](https://alice-lang.org/documentation/concurrency/race-safety.md)
