# How to make code that reads and writes to a variable thread safe?

**URL:** <https://discourse.julialang.org/t/how-to-make-code-that-reads-and-writes-to-a-variable-thread-safe/86961>\
**Category:** General Usage\
**Tags:** question\
**Created:** [September 8, 2022, 8:09pm UTC](https://discourse.julialang.org/t/how-to-make-code-that-reads-and-writes-to-a-variable-thread-safe/86961 "2022-09-08T20:09:12Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![tictaccat](https://avatars.discourse-cdn.com/v4/letter/t/9f8e36/32.png) [@tictaccat](https://discourse.julialang.org/u/tictaccat)\
**Post date:** [September 8, 2022, 8:09pm UTC](https://discourse.julialang.org/t/how-to-make-code-that-reads-and-writes-to-a-variable-thread-safe/86961/1 "2022-09-08T20:09:12Z")

</div>

The following (pseudo)code is not thread-safe:

```julia
mutable struct MutableState
     x::Int
end

function f(state)
     y = state.x 
     z = y^2
     state.x = z
end

state = MutableState(3)
# now run f(state) in parallel from many different threads 

```

My question is: how can I make this thread-safe? The key is that I read from `state.x`, do something, and then write to it. Can this be done using `@atomic` on the field `x`, and if so with which memory ordering requirement and on which operations do I put `@atomic`? (Just the write, or also the read?)

---

<div class="post-metadata">

**Author:** ![jmair](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jmair/32/35117_2.png) [@jmair](https://discourse.julialang.org/u/jmair)\
**Post date:** [September 9, 2022, 7:23am UTC](https://discourse.julialang.org/t/how-to-make-code-that-reads-and-writes-to-a-variable-thread-safe/86961/2 "2022-09-09T07:23:05Z")

</div>

You can make operations like this thread safe by using a lock (a SpinLock is usually a good choice [Multi-Threading · The Julia Language](https://docs.julialang.org/en/v1/base/multi-threading/#Low-level-synchronization-primitives)). However, this will basically nullify any parallelism so you should make sure that this is not the only part of the code that is run in parallel.

```julia
using Threads
Base.@kwdef mutable struct MutableState
     x::Int
     lock::SpinLock = SpinLock()
end

function f(state::MutableState)
     lock (state.lock) do 
         y = state.x 
         z = y^2
         state.x = z
    end
end

```

This will mean the read, compute and write are all done sequentially.
