Why does Interlocked.Exchange not support Boolean type?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Interlocked.Exchange is meant for atomic state changes, but its API is centered on machine-friendly numeric and reference types rather than bool. In practice, .NET code that needs a lock-free flag usually stores 0 or 1 in an int and uses Interlocked on that field.
Why bool Is Not the Normal Interlocked Primitive
Interlocked operations map closely to CPU-supported atomic instructions. Those instructions are most natural for aligned word-sized values such as integers, pointers, and references. A Boolean expresses a yes-or-no meaning well, but it is not the main type the Interlocked API was designed around.
The design goal of Interlocked is not to support every CLR type. It is to expose a small set of atomic building blocks that map cleanly to the runtime and to common synchronization patterns.
That is why the practical question is not "how do I atomically exchange a bool" but "how do I represent a thread-safe flag in a way that works naturally with the available atomic primitives."
Use an Integer as the Flag
The usual pattern is:
- '
0means false' - '
1means true'
Then use Interlocked.Exchange or Interlocked.CompareExchange on the int.
This gives you atomic updates and predictable memory-visibility behavior without needing a Boolean overload.
Why a Plain bool Is Not Enough
Even if a bool field looks simple, the real concurrency problem is not just whether the write fits in memory. It is whether multiple threads observe the right ordering and whether a state transition is performed atomically.
That is why Interlocked and Volatile exist. They describe intent explicitly:
- '
Interlockedfor atomic read-modify-write operations' - '
Volatile.ReadandVolatile.Writefor visibility and ordering'
A shared Boolean flag can be safe in some limited cases, but once you need atomic transitions such as "set this only if it was previously clear," an integer plus Interlocked is the clearer tool.
Exchange Versus CompareExchange
Many flag problems do not actually want unconditional exchange. They want compare-and-swap semantics:
This means "set the flag to 1 only if it is currently 0." That is often the real requirement behind single-initialization or single-entry code paths.
So the absence of a Boolean overload matters less than picking the correct atomic primitive for the state transition you need.
The Broader Lesson
The Interlocked API nudges you toward a useful mental model: choose a representation that works cleanly with low-level atomic operations. For .NET, that usually means using integers or references for lock-free coordination and interpreting them at the application level.
That might feel slightly less elegant than a bool, but it is a more explicit fit for concurrency code.
Common Pitfalls
- Treating
boolas the natural lock-free flag type just because the business meaning is true or false. - Using ordinary reads and writes on shared state when the program actually needs atomic transitions or visibility guarantees.
- Choosing
Exchangewhen the real problem calls forCompareExchange. - Forgetting
Volatile.Reador another synchronization mechanism when reading the flag later. - Writing lock-free code because it looks clever instead of because the concurrency requirements actually justify it.
Summary
- '
Interlocked.Exchangeis built around atomic primitives that map naturally to integers and references.' - In .NET, thread-safe flags are commonly represented as
intvalues0and1. - Use
Interlocked.Exchangefor unconditional state changes andCompareExchangefor compare-and-swap semantics. - The real issue is synchronization and memory visibility, not just whether the value is logically boolean.
- Pick the representation that matches the atomic operation you need, not just the business meaning of the flag.

